获取用户/团队对某条记录的权限,共享某条记录的某些权限给指定用户/团队的方法

学向勤中得,萤窗万卷书。这篇文章主要讲述获取用户/团队对某条记录的权限,共享某条记录的某些权限给指定用户/团队的方法相关的知识,希望能为你提供帮助。
我是微软Dynamics 365 & Power Platform方面的工程师/顾问罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复444或者20210602可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!
很多朋友已经发现了(应该是2021 Release 1新增的feature),在Dynamics 365中打开实体记录后,命令栏可以看到一个【Check Access】的按钮。

获取用户/团队对某条记录的权限,共享某条记录的某些权限给指定用户/团队的方法

文章图片

点击后默认展示的是当前用户对这个记录的权限,下图是一个示例。还可以更改 【User lookup】旁边的查找字段的值来查看其他用户对这个记录的权限。
获取用户/团队对某条记录的权限,共享某条记录的某些权限给指定用户/团队的方法

文章图片



根据官方文档 Check your user access to a record 的说法,用户通过如如下四种方式获取对记录的权限,我就不一一解释了,最后一个Hierarchy access默认情况下是关闭的,需要打开才能看到效果。用户对一条记录的权限是如何【算出来的】可以参考官方文档 How access to a record is determined 。
Access typeDescription
OwnershipUser owns the record or belongs to a team that owns the record.
Role accessUser has access to perform an action on a record because of their security role.
Shared accessThe record is shared with a user, team, or organization by a user that has appropriate share rights.
Hierarchy accessHierarchy access only takes place if hierarchy security management is turned on for the organization and the entity. The user also needs to be a manager.


今天我的重点内容是将如何通过Web API来获取某个用户对某条记录的权限,我这里以我要查询某个用户(systemuserid=2398ac30-008e-eb11-b1ac-002248569b73) 对某个联系人(contactid=be3ea431-b3c1-eb11-bacc-000d3ac81152)的权限为例来查看,我这里使用的代码如下,主要是通过 RetrievePrincipalAccessInfo Function 来查询的。
特别值得注意的是,如果要检查的用户对这条记录没有任何权限,那么执行会出错。所以当返回的请求 status 不是200的时候需要加入异常处理逻辑。
var clientUrl = Xrm.Utility.getGlobalContext().getClientUrl(); var userId = "2398ac30-008e-eb11-b1ac-002248569b73"; var contactId = "be3ea431-b3c1-eb11-bacc-000d3ac81152"; var req = new XMLHttpRequest() req.open("GET", clientUrl + "/api/data/v9.2/systemusers(" + userId + ")/Microsoft.Dynamics.CRM.RetrievePrincipalAccessInfo(ObjectId=" + contactId + ",EntityName=\'contact\')"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4) { req.onreadystatechange = null; if (this.status == 200) { var responseJSON = JSON.parse(this.responseText); var grantedAccessrights = JSON.parse(responseJSON.AccessInfo).GrantedAccessRights; console.log(grantedAccessrights); } else { console.log("用户对改记录没有任何权限"); } } } req.send();



查询出来的结果,这个用户对这个记录只有Append和AppendTo权限(console.log输出的值是 AppendAccess, AppendToAccess ),没有其他权限。这是示例返回结果:
{ "@odata.context":"https://luoyongdemo.crm5.dynamics.com/api/data/v9.2/$metadata#Microsoft.Dynamics.CRM.RetrievePrincipalAccessInfoResponse", "AccessInfo":{ "CallerPrincipal":{ "PrincipalId":"2398ac30-008e-eb11-b1ac-002248569b73", "Type":8, "IsUserPrincipal":true }, "OwnerPrincipal":{ "PrincipalId":"7001a536-008e-eb11-b1ac-002248569b73", "Type":8, "IsUserPrincipal":true }, "ObjectId":"be3ea431-b3c1-eb11-bacc-000d3ac81152", "ObjectTypeCode":2, "EntityName":"contact", "ObjectBusinessUnitId":"32486a65-4d8b-eb11-b1ac-0022485760be", "RightsToCheck":"ReadAccess, WriteAccess, AppendAccess, AppendToAccess, CreateAccess, DeleteAccess, ShareAccess, AssignAccess", "RoleAcce***ights":"AppendAccess, AppendToAccess", "PoaAcce***ights":"None", "HsmAcce***ights":"None", "GrantedAcce***ights":"AppendAccess, AppendToAccess", "Messages":[ "PrincipalHasOwnerPrincipalWithAtLeastBasicPrivilegeDepth = False", "EntityUserGroupRights = None", "MinimumPrivilegeDepthRequired = Global" ], "EntityOwnershipTypeMask":1, "CallerInfo":{ "IsSystemUser":false, "IsSupportUser":false, "IsAdministrator":false, "IsCustomizer":false, "IsDisabled":false, "IsIntegrationUser":false, "Teams":null, "Roles":null }, "ReadOnlyState":"UserAndOrgFullAccess", "IsHsmEnabled":false, "HsmInfo":null, "AccessOrigin":null } }



那我如何共享权限给这个用户呢?比如我共享读和修改权限给这个用户,如何做?主要是通过 GrantAccess Action 来做,下面是示例代码:
var clientUrl = Xrm.Utility.getGlobalContext().getClientUrl(); var userId = "2398ac30-008e-eb11-b1ac-002248569b73"; var contactId = "be3ea431-b3c1-eb11-bacc-000d3ac81152"; var reqContent = { "Target": "contacts(" + contactId + ")", "PrincipalAccess": { "Principal": { "systemuserid": userId, "@odata.type": "Microsoft.Dynamics.CRM.systemuser" }, "AccessMask": "ReadAccess,WriteAccess" } }; var req = new XMLHttpRequest() req.open("POST", clientUrl + "/api/data/v9.2/GrantAccess"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4) { req.onreadystatechange = null; if (this.status == 204) { console.log("授权成功!"); } } } req.send(JSON.stringify(reqContent));



首先通过共享菜单来看,的确是共享了读和写权限给这个用户。
获取用户/团队对某条记录的权限,共享某条记录的某些权限给指定用户/团队的方法

文章图片

然后再用前面的代码 RetrievePrincipalAccessInfo Function 去查就会看到返回的权限多了,变成 ReadAccess, WriteAccess, AppendAccess, AppendToAccess 。
我们用Check Access按钮来看,也可以知道这个Read权限是通过共享授予给这个用户的。
获取用户/团队对某条记录的权限,共享某条记录的某些权限给指定用户/团队的方法

文章图片

当然有共享,就有取消共享,取消共享可以使用 ModifyAccess Action ,示例代码如下,这个时候传递的 AccessMask 元素的值为null就可以。
var clientUrl = Xrm.Utility.getGlobalContext().getClientUrl(); var userId = "2398ac30-008e-eb11-b1ac-002248569b73"; var contactId = "be3ea431-b3c1-eb11-bacc-000d3ac81152"; var reqContent = { "Target": "contacts(" + contactId + ")", "PrincipalAccess": { "Principal": { "systemuserid": userId, "@odata.type": "Microsoft.Dynamics.CRM.systemuser" }, "AccessMask": null } }; var req = new XMLHttpRequest() req.open("POST", clientUrl + "/api/data/v9.2/ModifyAccess"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4) { req.onreadystatechange = null; if (this.status == 204) { console.log("替换共享给用户的权限成功!"); } } } req.send(JSON.stringify(reqContent));



如果你说我只想保留共享给他的读取权限,那也很简单,稍微修改下代码,就是输入参数中 AccessMask 元素传递要保留的权限即可。
var clientUrl = Xrm.Utility.getGlobalContext().getClientUrl(); var userId = "2398ac30-008e-eb11-b1ac-002248569b73"; var contactId = "be3ea431-b3c1-eb11-bacc-000d3ac81152"; var reqContent = { "Target": "contacts(" + contactId + ")", "PrincipalAccess": { "Principal": { "systemuserid": userId, "@odata.type": "Microsoft.Dynamics.CRM.systemuser" }, "AccessMask": "ReadAccess" } }; var req = new XMLHttpRequest() req.open("POST", clientUrl + "/api/data/v9.2/ModifyAccess"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4) { req.onreadystatechange = null; if (this.status == 204) { console.log("替换共享给用户的权限成功!"); } } } req.send(JSON.stringify(reqContent));



当然通过Power Automate中的flow也是可以做共享的,通过Microsoft Dataverse 这个Connector中的Perform an unbound action步骤来执行,截图示例如下:
【获取用户/团队对某条记录的权限,共享某条记录的某些权限给指定用户/团队的方法】
获取用户/团队对某条记录的权限,共享某条记录的某些权限给指定用户/团队的方法

文章图片


    推荐阅读