Condividi tramite


Come pulire l'accesso ereditato

Questo articolo illustra come rimuovere l'accesso ereditato per i record quando la configurazione a catena di una tabella cambia in Microsoft Dataverse.

Sintomi

Dopo che il comportamento a catena di una relazione di tabella per l'azione Reparent o Share è stato modificato in No Cascade, si continua ad avere accesso ai record correlati che devono essere rimossi.

Gli utenti possono segnalare di avere accesso imprevisto ai record. È possibile verificare l'accesso ai record correlati in due modi: usando la funzionalità Controlla accesso o il RetrieveAccessOrigin messaggio.

Usare la funzionalità Controlla accesso

Usare la funzionalità Controlla accesso nelle app basate su modello per controllare chi può accedere a un record. Gli amministratori possono usare questa funzionalità per controllare i singoli utenti o tutti gli utenti che hanno accesso a un record.

Quando si usa il controllo di accesso, viene visualizzato un elenco dei motivi per cui un utente ha accesso. Alcuni di questi motivi indicano che la condivisione è stata concessa a causa dell'accesso a un record correlato. Ad esempio:

  • Il record è stato condiviso con me perché ho accesso al record correlato.
  • Il record è stato condiviso con i team di cui sono membro perché il team ha accesso al record correlato.

Usare il messaggio RetrieveAccessOrigin

Gli sviluppatori possono usare il RetrieveAccessOrigin messaggio per rilevare quali utenti hanno accesso a un record. Questo messaggio restituisce una frase che descrive il motivo per cui l'utente ha accesso. Uno dei risultati seguenti indica che l'accesso è stato concesso a causa della condivisione di un record correlato:

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

Per altre informazioni, vedere Determinare il motivo per cui un utente ha accesso con il codice.

Causa

Quando il comportamento a catena per una relazione di tabella cambia, Dataverse avvia un processo asincrono per rimuovere l'accesso concesso in precedenza agli utenti. Tuttavia, questo processo potrebbe non riuscire, con conseguente mantenimento dell'accesso da parte degli utenti.

Risoluzione

Il primo passaggio per risolvere questo problema consiste nel ricreare il processo di sistema per rimuovere l'accesso. Se il processo non riesce, uno sviluppatore può usare il ResetInheritedAccess messaggio per applicare la modifica a un set specificato di record.

Ricreare il processo di sistema per rimuovere l'accesso

Gli sviluppatori possono usare il CreateAsyncJobToRevokeInheritedAccess messaggio per provare di nuovo a creare un processo asincrono.

Usare la 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);
}

Altre informazioni sull'uso dei messaggi con l'SDK per .NET.

L'azione CreateAsyncJobToRevokeInheritedAccess crea un nuovo processo asincrono denominato RevokeInheritedAccess. È possibile monitorare l'esito positivo di questo processo. Per altre informazioni, vedere Monitoraggio dei processi di sistema o gestione dei processi di sistema con il codice.

Reimpostare l'accesso ereditato

Se la ricreazione del processo di sistema per rimuovere l'accesso non riesce, uno sviluppatore con privilegi di amministratore di sistema o di personalizzazione del sistema può usare il ResetInheritedAccess messaggio per definire come destinazione un subset di record corrispondenti. Potrebbe essere necessario usare questo messaggio più volte per rimuovere l'accesso a tutti i record.

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

Altre informazioni sull'uso dei messaggi con l'SDK per .NET.

Il ResetInheritedAccess messaggio tenta di essere eseguito in modo sincrono quando non sono presenti molti record corrispondenti. ResetInheritedAccessResponse Il valore termina quindi con ExecutionMode : Sync. Se sono presenti molti record corrispondenti, l'operazione richiede più tempo e il valore termina con ExecutionMode : Async. Viene creato un processo di sistema denominato Denormalization_PrincipalObjectAccess_principalobjectaccess:<caller ID> ed è possibile monitorare l'esito positivo di tale processo. Per altre informazioni, vedere Monitoraggio dei processi di sistema o gestione dei processi di sistema con il codice.

Il ResetInheritedAccess messaggio richiede una query FetchXml per identificare i record. Questa query deve soddisfare i requisiti seguenti:

  • Usare la principalobjectaccesstabella (POA).
  • Restituisce solo la principalobjectaccessid colonna.
  • Non deve includere elementi link-entity . Non è possibile aggiungere un join a un'altra tabella.
  • Filtrare solo le colonne della principalobjectaccess tabella.

Questa tabella è disponibile per l'API Web come tipo di entità principalobjectaccess. Non è incluso nel riferimento a tabelle/entità Dataverse perché la tabella POA non supporta alcun tipo di operazione di modifica diretta dei dati. È necessario conoscere le colonne di questa tabella per comporre la query FetchXml.

Colonne di tabella POA

È necessario comporre una query FetchXml usando solo queste colonne.

Nome logico Tipo Descrizione
accessrightsmask Numero intero Contiene i valori dei membri dell'enumerazione AccessRights combinati per i diritti di accesso che l'entità dispone direttamente.
changedon DateTime Data dell'ultima modifica dell'accesso dell'entità al record.
inheritedaccessrightsmask Numero intero Contiene i valori dei membri dell'enumerazione AccessRights combinati per i diritti di accesso applicati a causa dell'ereditarietà.
objectid Identificatore univoco ID del record a cui l'entità può accedere.
objecttypecode Numero intero Valore EntityMetadata.ObjectTypeCode che corrisponde alla tabella. Questo valore non è necessariamente lo stesso per ambienti diversi. Per le tabelle personalizzate, viene assegnato in base all'ordine in cui è stata creata la tabella. Per ottenere questo valore, potrebbe essere necessario visualizzare i metadati per la tabella. Sono disponibili diversi strumenti della community per trovarlo. Ecco una soluzione di Microsoft: Esplorare le definizioni di tabella nell'ambiente.
principalid Identificatore univoco ID dell'utente o del team a cui è possibile accedere.
principalobjectaccessid Identificatore univoco Chiave primaria della tabella POA.
principaltypecode Numero intero Codice di tipo dell'entità. SystemUser = 8, Team = 9.

I valori dei membri dell'enumerazione AccessRights seguenti si applicano alle accessrightsmask colonne e inheritedaccessrightsmask :

Tipo di accesso Valore Descrizione
None 0 Nessun accesso.
Read 1 Diritto di lettura di un record.
Write 2 Diritto di aggiornamento di un record.
Append 4 Diritto di accodare il record specificato a un altro record.
AppendTo 16 Diritto di accodare un altro record al record specificato.
Create 32 Diritto per creare un record.
Delete 65,536 Diritto di eliminare un record.
Share 262,144 Diritto di condividere un record.
Assign 524,288 Diritto di assegnare il record specificato a un altro utente o team.

È possibile che il inheritedaccessrightsmask valore sia in genere 135.069.719. Questo valore include tutti i tipi di accesso ad eccezione Createdi , che non è necessario perché questi diritti si applicano solo ai record già creati.

Esempi di FetchXml

Questa sezione include alcuni esempi di query FetchXml che è possibile usare con il ResetInheritedAccess messaggio. Per altre informazioni, vedere Usare FetchXML per costruire una query.

Reimpostare l'accesso ereditato concesso a un determinato utente per un account specifico
<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>
Reimpostare l'accesso ereditato concesso a tutte le righe figlio per un tipo di oggetto specificato
<fetch>
    <entity name="principalobjectaccess">
        <attribute name="principalobjectaccessid"/>
        <filter type="and">
            <condition attribute="objecttypecode" operator="eq" value="10042" />
        </filter>
    </entity>
</fetch>
Reimpostare l'accesso ereditato concesso a un utente specificato per tutti i tipi di oggetto
<fetch>
    <entity name="principalobjectaccess">
        <attribute name="principalobjectaccessid"/>
        <filter type="and">
            <condition attribute="principalid" operator="eq" value="9b5f621b-584e-423f-99fd-4620bb00bf1f" />
        </filter>
    </entity>
</fetch>