Очистка унаследованного доступа
В этой статье описывается, как удалить унаследованный доступ для записей при изменении каскадной конфигурации таблицы в Microsoft Dataverse.
Симптомы
После изменения каскадного поведения табличного отношения для действия Reparent или Share на No Cascade у вас по-прежнему будет доступ к связанным записям, которые следует удалить.
Проверка доступа к связанным записям
Пользователи могут сообщать о том, что у них есть непредвиденный доступ к записям. Существует два способа проверки доступа к связанным записям: с помощью функции проверки доступа или RetrieveAccessOrigin
сообщения.
Использование функции проверки доступа
Используйте функцию проверки доступа в приложениях на основе модели, чтобы проверка, у кого есть доступ к записи. Администраторы могут использовать эту функцию для проверка отдельных пользователей или всех пользователей, имеющих доступ к записи.
При использовании средства проверки доступа отображается список причин, по которым у пользователя есть доступ. Некоторые из этих причин указывают на то, что общий доступ был предоставлен из-за доступа к связанной записи. Например:
- Мне предоставили доступ к записи, так как у меня есть доступ к связанной записи.
- Запись была предоставлена командам, членом которой я являюсь, так как у команды есть доступ к связанной записи.
Использование сообщения RetrieveAccessOrigin
Разработчики могут использовать сообщение, RetrieveAccessOrigin
чтобы определить, какие пользователи имеют доступ к записи. Это сообщение возвращает предложение, описывающее, почему у пользователя есть доступ. Любой из следующих результатов указывает на то, что доступ был предоставлен из-за общего доступа к связанной записи:
PrincipalId is owner of a parent entity of object (<record ID>)
PrincipalId is member of team (<team ID>) who is owner of a parent entity of object (<record ID>)
PrincipalId is member of organization (<organization ID>) who is owner of a parent entity of object (<record ID>)
PrincipalId has access to (<parent record ID>) through hierarchy security. (<parent record ID>) is owner of a parent entity of object (<record ID>)
Дополнительные сведения см. в разделе Определение того, почему у пользователя есть доступ к коду.
Причина
При изменении каскадного поведения для связи таблицы Dataverse запускает асинхронное задание для удаления ранее предоставленных пользователей доступа. Однако это задание может завершиться ошибкой, в результате чего пользователи сохранят доступ.
Решение
Первым шагом для устранения этой проблемы является повторное создание системного задания для удаления доступа. Если задание завершается сбоем, разработчик может использовать ResetInheritedAccess
сообщение для применения изменения к указанному набору записей.
Повторное создание системного задания для удаления доступа
Разработчики могут использовать сообщение для CreateAsyncJobToRevokeInheritedAccess
повторного создания асинхронного задания.
Используйте класс Microsoft.Xrm.Sdk.Messages.CreateAsyncJobToRevokeInheritedAccessRequest.
/// <summary>
/// Creates and executes an asynchronous cleanup job to revoke inherited access granted through cascading inheritance.
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance to use.</param>
/// <param name="relationshipSchemaName">The schema name of the entity relationship.</param>
public static void CreateAsyncJobToRevokeInheritedAccessExample(IOrganizationService service, string relationshipSchemaName)
{
var request = new Microsoft.Xrm.Sdk.Messages.CreateAsyncJobToRevokeInheritedAccessRequest()
{
RelationshipSchema = relationshipSchemaName
};
service.Execute(request);
}
Дополнительные сведения об использовании сообщений с пакетом SDK для .NET.
Действие CreateAsyncJobToRevokeInheritedAccess
создает новое асинхронное задание с именем RevokeInheritedAccess
. Вы можете отслеживать успешное выполнение этого задания. Дополнительные сведения см. в статье Мониторинг системных заданий или управление системными заданиями с помощью кода.
Сброс унаследованного доступа
Если повторное выполнение системного задания для удаления доступа завершается сбоем, разработчик с правами системного администратора или настройщика системы может использовать ResetInheritedAccess
сообщение для назначения подмножества соответствующих записей. Возможно, вам потребуется использовать это сообщение несколько раз, чтобы удалить доступ ко всем записям.
/// <summary>
/// Resets the inherited access for the matching records.
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance to use.</param>
/// <param name="fetchXml">The fetchxml query.</param>
public static void OutputResetInheritedAccess(IOrganizationService service, string fetchXml)
{
var parameters = new ParameterCollection()
{
{ "FetchXml", fetchXml}
};
var request = new OrganizationRequest()
{
RequestName = "ResetInheritedAccess",
Parameters = parameters
};
var response = service.Execute(request);
Console.WriteLine(response.Results["ResetInheritedAccessResponse"]);
}
Дополнительные сведения об использовании сообщений с пакетом SDK для .NET.
Сообщение ResetInheritedAccess
пытается выполняться синхронно, если совпадающих записей не так много.
ResetInheritedAccessResponse
Затем значение заканчивается на ExecutionMode : Sync
. Если совпадающих записей много, операция занимает больше времени, а значение заканчивается ExecutionMode : Async
на . Создается системное задание с именем Denormalization_PrincipalObjectAccess_principalobjectaccess:<caller ID>
, и вы можете отслеживать успешное выполнение этого задания. Дополнительные сведения см. в статье Мониторинг системных заданий или управление системными заданиями с помощью кода.
Сообщение ResetInheritedAccess
требует запроса FetchXml для идентификации записей. Этот запрос должен соответствовать следующим требованиям:
- Используйте таблицу
principalobjectaccess
(POA). - Возвращает только
principalobjectaccessid
столбец. - Не должен включать никакие
link-entity
элементы. Нельзя добавить соединение в другую таблицу. - Фильтровать только по столбцам
principalobjectaccess
таблицы.
Эта таблица доступна веб-API в качестве типа сущности principalobjectaccess. Он не включен в ссылку на таблицу или сущность Dataverse , так как таблица POA не поддерживает какие-либо операции прямого изменения данных. Чтобы составить запрос FetchXml, необходимо знать столбцы этой таблицы.
Столбцы таблицы POA
Необходимо создать запрос FetchXml, используя только эти столбцы.
Логическое имя | Тип | Описание |
---|---|---|
accessrightsmask |
Целое число | Содержит объединенные значения элементов перечисления AccessRights для прав доступа, которыми напрямую обладает субъект. |
changedon |
DateTime | Дата последнего изменения доступа субъекта к записи. |
inheritedaccessrightsmask |
Integer | Содержит объединенные значения элементов перечисления AccessRights для прав доступа, применяемых в связи с наследованием. |
objectid |
Уникальный идентификатор. | Идентификатор записи, к которому у субъекта есть доступ. |
objecttypecode |
Integer | Значение EntityMetadata.ObjectTypeCode , соответствующее таблице. Это значение не обязательно совпадает для разных сред. Для пользовательских таблиц он назначается в зависимости от порядка, в котором была создана таблица. Чтобы получить это значение, может потребоваться просмотреть метаданные таблицы. Существует несколько средств сообщества, чтобы найти это. Вот решение корпорации Майкрософт: просмотр определений таблиц в вашей среде. |
principalid |
Уникальный идентификатор. | Идентификатор пользователя или команды, у которого есть доступ. |
principalobjectaccessid |
Уникальный идентификатор. | Первичный ключ таблицы POA. |
principaltypecode |
Integer | Код типа субъекта.
SystemUser = 8, Team = 9. |
Следующие значения элементов перечисления AccessRights применяются к столбцам accessrightsmask
и inheritedaccessrightsmask
:
Тип доступа | Значение | Описание |
---|---|---|
None |
0 | Нет доступа |
Read |
1 | Право на чтение записи. |
Write |
2 | Право на обновление записи. |
Append |
4 | Право на добавление указанной записи к другой записи. |
AppendTo |
16 | Право на добавление другой записи к указанной записи. |
Create |
32 | Право на создание записи. |
Delete |
65,536 | Право на удаление записи. |
Share |
262,144 | Право на предоставление общего доступа к записи. |
Assign |
524,288 | Право на назначение указанной записи другому пользователю или команде. |
Вы можете увидеть, что inheritedaccessrightsmask
значение обычно равно 135 069 719. Это значение включает все типы доступа, Create
кроме , который не является обязательным, так как эти права применяются только к уже созданным записям.
Примеры fetchXml
В этом разделе приведены некоторые примеры запросов FetchXml, которые можно использовать с сообщением ResetInheritedAccess
. Дополнительные сведения см. в статье Создание запроса с помощью FetchXML.
Сброс унаследованного доступа, предоставленного определенному пользователю для определенной учетной записи
<fetch>
<entity name="principalobjectaccess">
<attribute name="principalobjectaccessid"/>
<filter type="and">
<condition attribute="principalid" operator="eq" value="9b5f621b-584e-423f-99fd-4620bb00bf1f" />
<condition attribute="objectid" operator="eq" value="B52B7A48-EAFB-ED11-884B-00224809B6C7" />
</filter>
</entity>
</fetch>
Сброс унаследованного доступа, предоставленного всем дочерним строкам для указанного типа объекта
<fetch>
<entity name="principalobjectaccess">
<attribute name="principalobjectaccessid"/>
<filter type="and">
<condition attribute="objecttypecode" operator="eq" value="10042" />
</filter>
</entity>
</fetch>
Сброс унаследованного доступа, предоставленного указанному пользователю для всех типов объектов
<fetch>
<entity name="principalobjectaccess">
<attribute name="principalobjectaccessid"/>
<filter type="and">
<condition attribute="principalid" operator="eq" value="9b5f621b-584e-423f-99fd-4620bb00bf1f" />
</filter>
</entity>
</fetch>