Freigeben über


Sauber des geerbten Zugriffs

In diesem Artikel wird beschrieben, wie Sie den geerbten Zugriff für Datensätze entfernen, wenn sich die Kaskadierungskonfiguration einer Tabelle in Microsoft Dataverse ändert.

Problembeschreibung

Nachdem das kaskadierende Verhalten einer Tabellenbeziehung für die Aktion Reparent oder Share in Keine Kaskade geändert wurde, haben Sie weiterhin Zugriff auf die verknüpften Datensätze, die entfernt werden sollen.

Benutzer können berichten, dass sie unerwarteten Zugriff auf Datensätze haben. Es gibt zwei Möglichkeiten, den Zugriff auf die zugehörigen Datensätze zu überprüfen: mithilfe der Funktion Zugriff überprüfen oder der RetrieveAccessOrigin Meldung.

Verwenden des Features "Zugriff überprüfen"

Verwenden Sie das Feature Zugriff überprüfen in modellgesteuerten Apps, um zu überprüfen, wer Zugriff auf einen Datensatz hat. Administratoren können dieses Feature verwenden, um einzelne Benutzer oder alle Benutzer zu überprüfen, die Zugriff auf einen Datensatz haben.

Wenn Sie die Zugriffsprüfung verwenden, wird eine Liste der Gründe angezeigt, warum ein Benutzer Zugriff hat. Einige dieser Gründe deuten darauf hin, dass die Freigabe aufgrund des Zugriffs auf einen verknüpften Datensatz gewährt wurde. Zum Beispiel:

  • Der Datensatz wurde für mich freigegeben, da ich Zugriff auf den zugehörigen Datensatz habe.
  • Der Datensatz wurde für Teams freigegeben, in denen ich Mitglied bin, da das Team Zugriff auf den entsprechenden Datensatz hat.

Verwenden der RetrieveAccessOrigin-Nachricht

Entwickler können die RetrieveAccessOrigin Meldung verwenden, um zu erkennen, welche Benutzer Zugriff auf einen Datensatz haben. Diese Meldung gibt einen Satz zurück, der beschreibt, warum der Benutzer zugriff hat. Eines der folgenden Ergebnisse gibt an, dass der Zugriff aufgrund der Freigabe eines verknüpften Datensatzes gewährt wurde:

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

Weitere Informationen finden Sie unter Ermitteln, warum ein Benutzer Zugriff mit Code hat.

Ursache

Wenn sich das kaskadierende Verhalten für eine Tabellenbeziehung ändert, startet Dataverse einen asynchronen Auftrag, um die zuvor gewährten Zugriffsbenutzer zu entfernen. Dieser Auftrag kann jedoch fehlschlagen, was dazu führt, dass Benutzer den Zugriff behalten.

Fehlerbehebung

Der erste Schritt zum Beheben dieses Problems besteht darin, den Systemauftrag neu zu erstellen, um den Zugriff zu entfernen. Wenn der Auftrag fehlschlägt, kann ein Entwickler die ResetInheritedAccess Meldung verwenden, um die Änderung auf einen angegebenen Satz von Datensätzen anzuwenden.

Erstellen Sie den Systemauftrag neu, um den Zugriff zu entfernen.

Entwickler können die CreateAsyncJobToRevokeInheritedAccess Meldung verwenden, um erneut einen asynchronen Auftrag zu erstellen.

Verwenden Sie die Microsoft.Xrm.Sdk.Messages.CreateAsyncJobToRevokeInheritedAccessRequest-Klasse.

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

Erfahren Sie mehr über die Verwendung von Nachrichten mit dem SDK für .NET.

Die CreateAsyncJobToRevokeInheritedAccess Aktion erstellt einen neuen asynchronen Auftrag namens RevokeInheritedAccess. Sie können den Erfolg dieses Auftrags überwachen. Weitere Informationen finden Sie unter Überwachen von Systemaufträgen oder Verwalten von Systemaufträgen mit Code.

Zurücksetzen des geerbten Zugriffs

Wenn das Erneute Erstellen des Systemauftrags zum Entfernen des Zugriffs fehlschlägt, kann ein Entwickler mit Systemadministrator- oder Systemanpassungsberechtigungen die ResetInheritedAccess Meldung verwenden, um eine Teilmenge übereinstimmender Datensätze als Ziel zu verwenden. Möglicherweise müssen Sie diese Meldung mehrmals verwenden, um den Zugriff auf alle Datensätze zu entfernen.

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

Erfahren Sie mehr über die Verwendung von Nachrichten mit dem SDK für .NET.

Die ResetInheritedAccess Nachricht versucht, synchron auszuführen, wenn nicht viele übereinstimmende Datensätze vorhanden sind. Dann endet der ResetInheritedAccessResponse Wert mit ExecutionMode : Sync. Wenn viele übereinstimmende Datensätze vorhanden sind, dauert der Vorgang länger, und der Wert endet mit ExecutionMode : Async. Ein Systemauftrag mit dem Namen Denormalization_PrincipalObjectAccess_principalobjectaccess:<caller ID> wird erstellt, und Sie können den Erfolg dieses Auftrags überwachen. Weitere Informationen finden Sie unter Überwachen von Systemaufträgen oder Verwalten von Systemaufträgen mit Code.

Die ResetInheritedAccess Nachricht erfordert eine FetchXml-Abfrage, um die Datensätze zu identifizieren. Diese Abfrage muss die folgenden Anforderungen erfüllen:

  • Verwenden Sie die principalobjectaccessTabelle (POA).
  • Gibt nur die principalobjectaccessid Spalte zurück.
  • Darf keine link-entity Elemente enthalten. Sie können keine Verknüpfung zu einer anderen Tabelle hinzufügen.
  • Filtern Sie nur nach Spalten der principalobjectaccess Tabelle.

Diese Tabelle steht der Web-API als Entitätstyp principalobjectaccess zur Verfügung. Es ist nicht in der Dataverse-Tabelle/Entitätsreferenz enthalten, da die POA-Tabelle keine Art von direkter Datenänderung unterstützt. Sie müssen die Spalten dieser Tabelle kennen, um die FetchXml-Abfrage erstellen zu können.

POA-Tabellenspalten

Sie müssen eine FetchXml-Abfrage nur mit diesen Spalten erstellen.

Logischer Name Typ Beschreibung
accessrightsmask Ganzzahl Enthält die kombinierten AccessRights-Enumerationsmemberwerte für die Zugriffsrechte, über die der Prinzipal direkt verfügt.
changedon DateTime Das letzte Datum, an dem sich der Zugriff des Prinzipals auf den Datensatz geändert hat.
inheritedaccessrightsmask Ganze Zahl Enthält die kombinierten AccessRights-Enumerationsmemberwerte für die Zugriffsrechte, die aufgrund der Vererbung angewendet werden.
objectid Eindeutiger Bezeichner Die ID des Datensatzes, auf den der Prinzipal Zugriff hat.
objecttypecode Ganze Zahl Der EntityMetadata.ObjectTypeCode-Wert , der der Tabelle entspricht. Dieser Wert ist für verschiedene Umgebungen nicht unbedingt identisch. Für benutzerdefinierte Tabellen wird sie basierend auf der Reihenfolge zugewiesen, in der die Tabelle erstellt wurde. Um diesen Wert zu erhalten, müssen Sie möglicherweise die Metadaten für die Tabelle anzeigen. Es gibt mehrere Communitytools, um dies zu finden. Hier ist eine Lösung von Microsoft: Durchsuchen von Tabellendefinitionen in Ihrer Umgebung.
principalid Eindeutiger Bezeichner Die ID des Benutzers oder Teams, das Zugriff hat.
principalobjectaccessid Eindeutiger Bezeichner Der Primärschlüssel der POA-Tabelle.
principaltypecode Ganze Zahl Der Typcode des Prinzipals. SystemUser = 8, Team = 9.

Die folgenden AccessRights-Enumerationsmemberwerte gelten für die accessrightsmask Spalten und inheritedaccessrightsmask :

Zugriffstyp Wert Beschreibung
None 0 Kein Zugriff.
Read 1 Das Recht zum Lesen eines Datensatzes.
Write 2 Das Recht zum Aktualisieren eines Datensatzes.
Append 4 Das Recht, den angegebenen Datensatz an einen anderen Datensatz anzufügen.
AppendTo 16 Das Recht, einen anderen Datensatz an den angegebenen Datensatz anzufügen.
Create 32 Das Recht zum Erstellen eines Datensatzes.
Delete 65,536 Das Recht zum Löschen eines Datensatzes.
Share 262,144 Das Recht, einen Datensatz zu teilen.
Assign 524,288 Das Recht, den angegebenen Datensatz einem anderen Benutzer oder Team zuzuweisen.

Möglicherweise ist der Wert in der inheritedaccessrightsmask Regel 135.069.719. Dieser Wert enthält alle Zugriffstypen mit Ausnahme Createvon , was nicht erforderlich ist, da diese Rechte nur für bereits erstellte Datensätze gelten.

FetchXml-Beispiele

Dieser Abschnitt enthält einige Beispiele für FetchXml-Abfragen, die Sie mit der ResetInheritedAccess Nachricht verwenden können. Weitere Informationen finden Sie unter Verwenden von FetchXML zum Erstellen einer Abfrage.

Zurücksetzen des geerbten Zugriffs, der einem bestimmten Benutzer für ein bestimmtes Konto gewährt wurde
<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>
Zurücksetzen des geerbten Zugriffs auf alle untergeordneten Zeilen für einen angegebenen Objekttyp
<fetch>
    <entity name="principalobjectaccess">
        <attribute name="principalobjectaccessid"/>
        <filter type="and">
            <condition attribute="objecttypecode" operator="eq" value="10042" />
        </filter>
    </entity>
</fetch>
Zurücksetzen des geerbten Zugriffs auf einen angegebenen Benutzer für alle Objekttypen
<fetch>
    <entity name="principalobjectaccess">
        <attribute name="principalobjectaccessid"/>
        <filter type="and">
            <condition attribute="principalid" operator="eq" value="9b5f621b-584e-423f-99fd-4620bb00bf1f" />
        </filter>
    </entity>
</fetch>