Como limpo acesso herdado

Este artigo apresenta como remover o acesso herdado para registros quando a configuração em cascata de uma tabela é alterada no Microsoft Dataverse.

Sintomas

Depois que o comportamento em cascata de uma relação de tabela para a ação Reparent ou Share for alterado para No Cascade, você continuará tendo acesso aos registros relacionados que devem ser removidos.

Os usuários podem relatar que têm acesso inesperado aos registros. Há duas maneiras de verificar o acesso aos registros relacionados: usando o recurso Verificar Acesso ou a RetrieveAccessOrigin mensagem.

Usar o recurso Verificar Acesso

Use o recurso Verificar Acesso em aplicativos controlados por modelos para marcar quem tem acesso a um registro. Os administradores podem usar esse recurso para marcar usuários individuais ou todos os usuários que têm acesso a um registro.

Ao usar o verificador de acesso, você verá uma lista de motivos pelos quais um usuário tem acesso. Alguns desses motivos indicam que o compartilhamento foi concedido devido ao acesso a um registro relacionado. Por exemplo:

  • O registro foi compartilhado comigo porque tenho acesso ao registro relacionado.
  • O registro foi compartilhado com a equipe da qual sou membro porque a equipe tem acesso ao registro relacionado.

Usar a mensagem RetrieveAccessOrigin

Os desenvolvedores podem usar a RetrieveAccessOrigin mensagem para detectar quais usuários têm acesso a um registro. Esta mensagem retorna uma frase que descreve por que o usuário tem o acesso. Qualquer um dos resultados a seguir indica que o acesso foi concedido devido ao compartilhamento de um registro relacionado:

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>)

Para obter mais informações, consulte Determinar por que um usuário tem acesso com código.

Motivo

Quando o comportamento em cascata de uma relação de tabela é alterado, o Dataverse inicia um trabalho assíncrono para remover os usuários de acesso que foram concedidos anteriormente. No entanto, esse trabalho pode falhar, resultando em usuários mantendo o acesso.

Solução

A primeira etapa para resolve esse problema é recriar o trabalho do sistema para remover o acesso. Se o trabalho falhar, um desenvolvedor poderá usar a ResetInheritedAccess mensagem para aplicar a alteração a um conjunto de registros especificado.

Recriar o trabalho do sistema para remover o acesso

Os desenvolvedores podem usar a CreateAsyncJobToRevokeInheritedAccess mensagem para tentar criar um trabalho assíncrono novamente.

Use a classe 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);
}

Saiba mais sobre como usar mensagens com o SDK para .NET.

A CreateAsyncJobToRevokeInheritedAccess ação cria um novo trabalho assíncrono chamado RevokeInheritedAccess. Você pode monitorar o sucesso deste trabalho. Para obter mais informações, consulte monitoramento de trabalhos do sistema ou gerenciamento de trabalhos do sistema com código.

Redefinir o acesso herdado

Se a recriação do trabalho do sistema para remover o acesso falhar, um desenvolvedor com privilégios de administrador do sistema ou personalizador de sistema poderá usar a ResetInheritedAccess mensagem para direcionar um subconjunto de registros correspondentes. Talvez seja necessário usar essa mensagem várias vezes para remover o acesso a todos os registros.

/// <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"]);
}

Saiba mais sobre como usar mensagens com o SDK para .NET.

A ResetInheritedAccess mensagem tenta executar de forma síncrona quando não há muitos registros correspondentes. Em seguida, o ResetInheritedAccessResponse valor termina com ExecutionMode : Sync. Se houver muitos registros correspondentes, a operação levará mais tempo e o valor terminará com ExecutionMode : Async. Um trabalho do sistema chamado Denormalization_PrincipalObjectAccess_principalobjectaccess:<caller ID> é criado e você pode monitorar o sucesso desse trabalho. Para obter mais informações, consulte monitoramento de trabalhos do sistema ou gerenciamento de trabalhos do sistema com código.

A ResetInheritedAccess mensagem requer uma consulta FetchXml para identificar os registros. Essa consulta deve atender aos seguintes requisitos:

  • Use a principalobjectaccesstabela (POA).
  • Retornar somente a principalobjectaccessid coluna.
  • Não deve incluir nenhum link-entity elemento. Você não pode adicionar uma junção a outra tabela.
  • Filtrar somente em colunas da principalobjectaccess tabela.

Esta tabela está disponível para a API Web como o tipo de entidade principalobjectaccess. Ela não está incluída na referência de tabela/entidade do Dataverse porque a tabela POA não dá suporte a nenhum tipo de operação de modificação direta de dados. Você precisa conhecer as colunas desta tabela para compor a consulta FetchXml.

Colunas de tabela POA

Você precisa compor uma consulta FetchXml usando apenas essas colunas.

Nome lógico Tipo Descrição
accessrightsmask Inteiro Contém os valores de membro de enumeração do AccessRights combinados para os direitos de acesso que a entidade de segurança tem diretamente.
changedon DateTime A última data em que o acesso da entidade ao registro foi alterado.
inheritedaccessrightsmask Número inteiro Contém os valores de membro de enumeração do AccessRights combinados para os direitos de acesso que são aplicados devido à herança.
objectid Identificador exclusivo A ID do registro ao qual a entidade de segurança tem acesso.
objecttypecode Número inteiro O valor EntityMetadata.ObjectTypeCode que corresponde à tabela. Esse valor não é necessariamente o mesmo para ambientes diferentes. Para tabelas personalizadas, ela é atribuída com base na ordem na qual a tabela foi criada. Para obter esse valor, talvez seja necessário exibir os metadados da tabela. Há várias ferramentas da comunidade para encontrar isso. Aqui está uma solução da Microsoft: procurar definições de tabela em seu ambiente.
principalid Identificador exclusivo A ID do usuário ou da equipe que tem acesso.
principalobjectaccessid Identificador exclusivo A chave primária da tabela POA.
principaltypecode Número inteiro O código de tipo da entidade de segurança. SystemUser = 8, Team = 9.

Os seguintes valores de membro de enumeração AccessRights se aplicam às accessrightsmask colunas e inheritedaccessrightsmask :

Tipo de acesso Valor Descrição
None 0 Sem acesso.
Read 1 O direito de ler um registro.
Write 2 O direito de atualizar um registro.
Append 4 O direito de acrescentar o registro especificado a outro registro.
AppendTo 16 O direito de acrescentar outro registro ao registro especificado.
Create 32 O direito de criar um registro.
Delete 65,536 O direito de excluir um registro.
Share 262,144 O direito de compartilhar um registro.
Assign 524,288 O direito de atribuir o registro especificado a outro usuário ou equipe.

Você pode ver que o inheritedaccessrightsmask valor costuma ser 135.069.719. Esse valor inclui todos os tipos de acesso, exceto , Createo que não é necessário porque esses direitos se aplicam apenas aos registros já criados.

Exemplos de FetchXml

Esta seção inclui alguns exemplos de consultas FetchXml que você pode usar com a ResetInheritedAccess mensagem. Para obter mais informações, consulte Usar FetchXML para construir uma consulta.

Redefinir o acesso herdado dado a um determinado usuário para uma conta específica
<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>
Redefinir o acesso herdado dado a todas as linhas filho para um tipo de objeto especificado
<fetch>
    <entity name="principalobjectaccess">
        <attribute name="principalobjectaccessid"/>
        <filter type="and">
            <condition attribute="objecttypecode" operator="eq" value="10042" />
        </filter>
    </entity>
</fetch>
Redefinir o acesso herdado dado a um usuário especificado para todos os tipos de objeto
<fetch>
    <entity name="principalobjectaccess">
        <attribute name="principalobjectaccessid"/>
        <filter type="and">
            <condition attribute="principalid" operator="eq" value="9b5f621b-584e-423f-99fd-4620bb00bf1f" />
        </filter>
    </entity>
</fetch>