Dynamics CRM 如何修复 Access Is Denied - ObjectTypeCode: 2500 的错误

最近被 Dynamics CRM 的权限配置问题恶心了一个星期,老是报“Access Is Denied”,几经波折,最后终于找到一个比较合适的解决方案,写个博客 mark 下来,方便以后查看。

首先,介绍一下权限设置的要求:

1.在根 Business Unit 下建立好 Security Role,并根据文档要求赋予 Sense Role 相关 Entity 及 CRM 系统的操作权限;

2.建立多个 Team,每个 Team 都有各自的权限配置,给 Team Role 赋予不同的 Security Role;

3.创建 User,但是不给 User Role 赋 Security Role,而是直接将 User 加到 Team 中,这样 User 也可以得到与 Team 相同的权限(但这个并不是User本身拥有的权限)。

然后,我来描述一下 Bug 是怎么产生的:

当我按照需求设置好 Security Role 的各种权限并添加完 Team 和 User 后,开始使用这些 User 在 CRM 系统上进行测试,当我测试完某个 Entity 的 BPF(Business Process Flow),返回到列表视图后,再次双击 Record 想进来再查看的时候,开始报错,如下图所示:

Dynamics CRM 如何修复 Access Is Denied - ObjectTypeCode: 2500 的错误

图1 Access Is Denied

      Acess Is Denied? 此时的我???Ok,这条 Record 进不去,那我换一条,双击,Access Is Denied。嗯???Ok,那我直接 New 一条 Record,Access Is Denied……

接下来,讲一下我艰难的排 BUG 过程:

既然发现了 Bug ,那么先来找找 Bug 是怎么被触发的。

Download Log File,从文件里可以得到以下的一段信息:

<Message>
SecLib::AccessCheckEx failed.
Returned hr = -2147187962,
ObjectID: f7014009-b409-e911-943a-00155d16b40a,
OwnerId: c062acbd-fcfc-e811-943a-00155d16b40a,
OwnerIdType: 8 and CallingUser: c062acbd-fcfc-e811-943a-00155d16b40a.
ObjectTypeCode: 2500,
objectBusinessUnitId: 9cfbf85c-3e0f-e911-8b87-e0aa182461d5,
AccessRights: WriteAccess
</Message>

第一眼看到 WriteAccess,我以为是 Security Role 没有设置好,检查了一下,设置没有问题,而且 Read 的权限也在正常运作,因为可以看到 Active View 里所有的 Record。接着在屏蔽了 JS 以及 Plugin 代码后,重新添加新的 system user 后,执行一步 BPF:OK,不出所料报了 Acess Is Denied 的错误,通过测试验证了这个 bug 跟 JS 以及 Plugin 代码无关,剩下就是要找出权限设置哪里出了差错。

现在,就讲一下这类bug要如何修复:

1.首先从下载下来的 log 中可以看到,ObjectTypeCode:2500,对 CRM 数据库新建查询,执行以下查询语句:

SELECT * from EntityView ORDER BY ObjectTypeCode

可以得到一个列表,并且可以在列表中查询到 ObjectTypeCode:2500 对应的 Entity Name 为 UserEntityUISettings

Dynamics CRM 如何修复 Access Is Denied - ObjectTypeCode: 2500 的错误

图2 数据库查询结果

2.在设置权限的时候我们可以看到这个 UserEntityUISettings 就在 Security Role -> Core Records -> User Entity UI Settings

Dynamics CRM 如何修复 Access Is Denied - ObjectTypeCode: 2500 的错误

图3 Security Role 设置

根据 log 上报缺少 Write 权限,那么我们在 Security Role 里面将整行权限全部点上(这里的设置也只能点一下,赋予了 User 级别的权限),然后使用 User 重新打开刚刚 Access Is Denied 的 Record:发现还是打不开,还是报了 Acess Is Denied ,还是报了 ObjectTypeCode:2500 的错误。

猜想:难道是 Team Role 的权限不能被带到 User Role 那边?于是在 System User 的 User Role 里勾上了这个 Security Role,再次使用 User 打开 Record,惊喜,所有的操作都可以正常执行,不再报 Acess Is Denied 的错误了(此刻内心简直思绪万千)。然而,bug 虽然解决了,但这个方式显然是不行的,因为如果在 User Role 里勾选上与 Team Role 一样的 Security Role 的话,那么通过将 User 加到 Team 里来获得权限这一点就已经失去了意义(除去 ownerid 为 Team 的情况),因为此时 User 自身已经拥有与 Team 相同的权限。

为了符合通过将 User 加入 Team 来获取权限这一需求,可以使用以下方法:

 新建一个叫做 UI 的 Security Role,在这个 Security Role 只赋予它 User Entity UI Setttings 的权限;
其他 Security Role 不赋予 User Entity UI Settings 权限,并且这些 Security Role 只供 Team Role 使用;
每个 System User 的 User Role 都使用 UI Security Role,不必勾选其他 Security Role。

Note:

这里再提一个奇怪的修复方法,也算是一个隐藏 bug,就是当你在 system user 的 User Role 那边勾选了一个具有 UserEntityUISettings 的 Security Role,并使用这个 user 去访问了之前无权限访问的 Record 后,这个时候我们再将 User Role 上勾选的 Security Role 取消,再去访问那些 Record,你可以发现都变成有权限访问了……没错,它就是如此的神奇,可能是存在“缓存”,或者勾选了之后会在数据库某张权限表上加了一条代表某种关系的记录,取消勾选又不会移除该条关系,关于具体原因我并没有深入探究,也不建议通过这种方式来修复这个 bug,因为当你新加了 Entity 实体后又会再次出现同样的错误,因为你之前并没有访问过。

总结:

最后总结一下,当出现“Acess Is Denied”相关的错误时,可以通过下载 log 文件,根据文件提示的 ObjectTypeCode 代码及其他相关的日志信息,在数据库中查询出相对应的 Entity Name,再具体修复该 bug。

参考:https://nishantrana.me/2018/05/15/seclibaccesscheckex-failed-objecttypecode-2500-accessrights-writeaccess-error-on-user-entity-ui-settings-in-dynamics-365/

上一篇:Java开发相关命名规范


下一篇:Oracle 相关查询