Очистка унаследованного доступа

В этой статье описывается, как удалить унаследованный доступ для записей при изменении каскадной конфигурации таблицы в 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>