Sicherheit

PowerPortalsPro bietet ein flexibles, codebasiertes Sicherheitsmodell, das es Ihnen ermöglicht, den Zugriff sowohl auf Tabellen- als auch auf Datensatzebene zu steuern. Sicherheit wird implementiert, indem Berechtigungshandler-Klassen erstellt und im Dependency Injection-Container registriert werden.

Überblick

Es gibt zwei Schnittstellen, die du je nach benötigtem Kontrollniveau implementieren kannst:

Tipp

Wenn Sie nur Kontrolle auf Tabellenebene benötigen (z. B. "authentifizierte Benutzer können diese Tabelle lesen"), verwenden Sie ITablePermissionHandler. Wenn Sie Datensatz-Logik benötigen (z. B. "Benutzer können nur Datensätze löschen, die sie besitzen"), verwenden ITableRecordPermissionHandlerSie .

Best Practice – an der Quelle filtern

Berechtigungshandler erzwingen den Zugriff, aber sie ersetzen das Filtern nicht. Datensatz-Handlers laufen, nachdem eine Seite mit Datensätzen aus Dataverse abgerufen wurde, daher verzerrt das Verstecken von Zeilen das Rasterpaging (eine Seite mit 50 kann weniger anzeigen) und die Gesamtanzahl und verschwendet Abfragen, die Zeilen abrufen, die dann verworfen werden. Wann immer Daten auf den aktuellen Benutzer beschränkt werden müssen, filtern Sie stattdessen auf Abfrageebene – mit einer IFetchXmlQueryFilterInterceptor (siehe unten) oder einer benutzerdefinierten Ansicht, die den aktuellen Benutzer berücksichtigt – sodass Dataverse nur die Zeilen zurückgibt, die der Benutzer sehen sollte, und die Rasterseite genau anpasst. Behalte die Berechtigungsbearbeiter als deine Durchsetzungsgarantie.

Dataverse-Native Security (Vorschau)

Das empfohlene Sicherheitsmodell für die Zukunft ermöglicht es Dataverse selbst , die Sicherheit für Ihre Portalnutzer durchzusetzen, basierend auf der einheitlichen Sicherheitsfunktion von Power Pages. Anstatt Berechtigungshandler im Code zu schreiben, verwalten Sie den Zugriff mit Standard-Dataverse-Sicherheitsrollen – denselben Rollen, Privilegien und Admin-Tools wie für interne Benutzer. Das Modell befindet sich derzeit in der Vorschau – sowohl Microsofts Funktion als auch Power Portals Pros Unterstützung dafür – und Power Portals Pro wird Microsofts Veröffentlichungsplan zur allgemeinen Verfügbarkeit folgen.

Wenn aktiviert, stellt PowerPortalsPro automatisch ein systemverwaltetes (C2) systemuser für jeden Portalkontakt bereit – bei der Registrierung für neue Kontakte und faul bei der Anmeldung für bestehende – zusammen mit dem powerpagesusermapping Datensatz, der den Kontakt, den Systemnutzer und Ihre Power Pages-Website verknüpft. Jeder Dataverse-Aufruf für die Sitzung imitiert dann diesen Systembenutzer, sodass die Sicherheitsrollen, die Power Pages mit deinen Webrollen und Tabellenberechtigungen synchronisiert, genau bestimmen, was der Nutzer sehen und tun kann. Die Sitzung trägt ein PortalUserType Off ContactStubUser , sodass Ihre Benutzeroberfläche diese bereitgestellten Benutzer immer von echten internen Benutzern unterscheiden kann.

Anmerkung

Um dieses Sicherheitsmodell zu verwenden, müssen Sie eine Power Pages-Website in Ihrer Dataverse-Umgebung erstellen – diese installiert die Microsoft-Framework-Komponenten und ermöglicht es Ihnen, die unified-security-Funktion zu aktivieren. Sie benötigen keinen bezahlten Power Pages-Plan und können die Website direkt nach der Installation und Aktivierung der Funktion löschen. Der von von belegte PowerPagesSiteId Power Pages-Site-Eintrag (powerpagesite) muss in der Umgebung vorhanden sein, da Benutzerzuordnungen und Synchronisation mit Sicherheitsrollen gegen ihn aufgelöst werden.

Aktivierung von Dataverse-Native-Sicherheit

Aktivieren Sie das System SecurityOptions auf Ihrem Server Program.csund geben Sie die ID Ihres Power Pages-Website-Datensatzes an:

Die Konfiguration wird beim Anwendungsstart überprüft: Wenn ProvisionSystemUsers aktiviert ist, PowerPagesSiteId muss gesetzt und auf einen bestehenden powerpagesite Datensatz aufgelöst werden, andernfalls startet die Anwendung nicht mit der Leitung.

Gewähren Sie Zugriff genau so wie Power Pages: Konfigurieren Sie Webrollen und Tabellenberechtigungen in der Power Pages Management App und weisen Sie Webrollen Kontakten zu (über die Management-App oder programmatisch). Die Plattform synchronisiert diese in automatisch generierte Sicherheitsrollen (benannt PowerPages_*) und weist sie automatisch zu, wenn sich die Web-Mitgliedschaft ändert – da die Konfiguration vollständig in Power Pages liegt, kann Ihr Portal ohne Widerstand zu einer tatsächlichen Power-Pages-Seite wechseln oder von ihnen zurückgehen. Beachten Sie, dass Rollen- und Privilegienänderungen von wenigen Sekunden bis zu ein paar Minuten dauern können, um durch die Dataverse-Caches zu laufen, bevor sie wirksam werden.

Folgen Sie der Schritt-für-Schritt-Einrichtungsanleitung

Anfang

1. Einen Berechtigungshandler erstellen

Erstelle eine Klasse, die oder ITableRecordPermissionHandlerimplementiertITablePermissionHandler. Setze die Eigenschaft Table auf den logischen Namen der Dataverse-Tabelle, auf die der Handler angewendet wird, und implementiere jede Berechtigungsmethode.

Hier ist ein einfaches Beispiel, das allen Benutzern für eine bestimmte Tabelle vollen Zugriff gewährt:

2. Registrieren in der Abhängigkeitsinjektion

Registrieren Sie Ihren Handler im DI-Container in der Program.cs Datei Ihres Projekts (oder in einer Service Collection Extension Methode):

Da Handler aus dem DI-Container aufgelöst werden, können Sie alle erforderlichen Services (wie Datenbankkontext oder Benutzerdienst) per Konstruktor-Injektion injizieren.

Rekordsicherheit auf Rekordniveau

Für Szenarien, in denen der Zugriff von dem spezifischen Datensatz abhängt, der bearbeitet wird, implementieren ITableRecordPermissionHandlerSie . Diese Schnittstelle erstreckt ITablePermissionHandler sich mit Überlastungen, die das empfangen.TableRecord

Das folgende Beispiel erlaubt es allen Benutzern, Datensätze global zu lesen, beschränkt jedoch die Schreibvorgänge auf Datensätze, die dem aktuellen Benutzer gehören:

Anmerkung

Die CanUpdateAsync Datensatzebene-Überladung stellt sowohl den Datensatz mit den vorgeschlagenen Aktualisierungen (recordWithUpdates) als auch den Datensatz im aktuell gespeicherten Zustand bereit (currentRecord), sodass Sie Werte vergleichen oder spezifische Feldänderungen validieren können.

Erforderliche Spalten

Die Eigenschaft RequiredColumns legt fest, welche Spalten abgerufen werden müssen, damit der Handler die Berechtigungen auf Datensatzebene auswerten kann. Das Framework fügt diese Spalten automatisch zu FetchXML-Abfragen hinzu, wenn sie noch nicht enthalten sind, sodass der Handler immer die benötigten Daten hat – selbst wenn die Ansicht oder Abfrage diese Spalten nicht enthält.

Das folgende Beispiel verwendet die ppp_owningportaluserid Nachschlagespalte, um den Zugriff auf Datensätze des aktuellen Benutzers einzuschränken:

Anmerkung

Wenn RequiredColumns eine leere Liste zurückgegeben wird und die Methoden auf Datensatzebene des Handlers nur verwendenrecord.Id, werden keine zusätzlichen Spalten zur Abfrage hinzugefügt. Die Eigenschaft owner wird immer von der Plattform bereitgestellt, unabhängig davon.RequiredColumns

FetchXML Abfragefilter-Interceptoren

Zusätzlich zur Sicherheit auf Tabellen- und Datensatzebene unterstützt IFetchXmlQueryFilterInterceptor PowerPortalsPro – eine Schnittstelle, mit der Sie FetchXML-Abfragen vor deren Ausführung anpassen können. Dies ist nützlich, um Zeilen-Filterung durchzusetzen, etwa indem sichergestellt wird, dass ein Benutzer nur Datensätze sehen kann, die ihm oder seinem Team gehören.

IFetchXmlQueryFilterInterceptorITablePermissionHandlererweitert , sodass jeder Abfanger auch tabellenbezogene Berechtigungen über die Table Eigenschaft und die Standardberechtigungsmethoden definiert. Die OnQueryAsync Methode des Interceptors wird nur für Abfragen aufgerufen, die auf die angegebene Tabelle abzielen.

Im Gegensatz zu Datensatz-Berechtigungshandlern, die jeden Datensatz nach dem Abruf evaluieren, ändern Abfragefilter-Interceptoren die Abfrage, bevor sie Dataverse erreicht. Herausgefilterte Datensätze werden nie abgerufen, was die Leistung und Sicherheit verbessert – und, was wichtig ist, die Raster-Auslagerung und die Gesamtzählung genau hält, da eine nach der Abruf angewandte Filterung Seiten zu kurz und Fehlzählungen führen würde.

1. Erstellen Sie einen Abfragefilter-Interceptor

Implementiere IFetchXmlQueryFilterInterceptor, setze die Table Eigenschaft auf den logischen Namen der Tabelle, implementiere die Berechtigungsmethoden und nutze die FetchXMLBuilder In, OnQueryAsync um Filter zur Abfrage hinzuzufügen. Der FetchXmlParameters Datensatz liefert das aktuelle Benutzer.EntityReference FetchXMLBuilder

Das folgende Beispiel beschränkt Abfragen in der contact Tabelle darauf, nur den Datensatz zurückzugeben, der dem aktuellen Benutzer entspricht:

2. Registrieren in der Abhängigkeitsinjektion

Registrieren Sie Ihren Interceptor sowohl als ein IFetchXmlQueryFilterInterceptor als auch als an ITablePermissionHandler , damit sowohl die Abfragefilterung als auch die Berechtigungen auf Tabellenebene angewendet werden. Mehrere Abfangsender können registriert werden, und jeder wird für Abfragen ausgeführt, die auf seine Tabelle abzielen.

Tipp

Da IFetchXmlQueryFilterInterceptor erweitert ITablePermissionHandler, übernimmt eine einzelne Klasse sowohl Berechtigungen auf Tabellenebene als auch Abfragefilterung. Die Methode OnQueryAsync wird nur für Abfragen aufgerufen, die mit der Table Eigenschaft des Interceptors übereinstimmen, sodass der Tabellenname innerhalb der Methode nicht überprüft werden muss.

Eingebaute Basisklassen

Das Framework stellt Basisklassen bereit, um gängige Sicherheitsmuster zu vereinfachen:

API-Referenz

ITablePermissionHandler Interface

Eigenschaften

Name
Typ
Default
Beschreibung
Tablestring
Logischer Name der Tabelle, auf die dieser Berechtigungshandler angewendet wird.
Name: Table
Typ: string
Beschreibung: Logischer Name der Tabelle, auf die dieser Berechtigungshandler angewendet wird.

Methoden

Name
Parameter
Typ
Beschreibung
CanAppendAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer einen Datensatz anhängen kann.
CanAppendToAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, einen Datensatz anzuhängen.
CanCreateAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, einen Datensatz zu erstellen.
CanDeleteAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer einen Datensatz löschen kann.
CanReadAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer einen Datensatz lesen kann.
CanUpdateAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer einen Datensatz aktualisieren kann.
Name: CanAppendAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer einen Datensatz anhängen kann.
Name: CanAppendToAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, einen Datensatz anzuhängen.
Name: CanCreateAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, einen Datensatz zu erstellen.
Name: CanDeleteAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer einen Datensatz löschen kann.
Name: CanReadAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer einen Datensatz lesen kann.
Name: CanUpdateAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer einen Datensatz aktualisieren kann.

ITableRecordPermissionHandler Interface

Eigenschaften

Name
Typ
Default
Beschreibung
RequiredColumnsList<string>
Liste von logischen Spaltennamen, die für diesen Handler abgerufen werden müssen, um Datensatzberechtigungen zu bewerten.
Tablestring
Logischer Name der Tabelle, auf die dieser Berechtigungshandler angewendet wird.
Name: RequiredColumns
Typ: List<string>
Beschreibung: Liste von logischen Spaltennamen, die für diesen Handler abgerufen werden müssen, um Datensatzberechtigungen zu bewerten.
Name: Table
Typ: string
Beschreibung: Logischer Name der Tabelle, auf die dieser Berechtigungshandler angewendet wird.

Methoden

Name
Parameter
Typ
Beschreibung
CanAppendAsyncGuid? userId
TableRecord record
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz anhängen kann.
CanAppendToAsyncGuid? userId
TableRecord record
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, den bereitgestellten Datensatz anzuhängen.
CanCreateAsyncGuid? userId
TableRecord record
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz erstellen kann.
CanDeleteAsyncGuid? userId
TableRecord record
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz löschen kann.
CanReadAsyncGuid? userId
TableRecord record
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz lesen kann.
CanUpdateAsyncGuid? userId
TableRecord recordWithUpdates
TableRecord currentRecord
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz aktualisieren kann.
Name: CanAppendAsync
Parameter: Guid? userId
TableRecord record
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz anhängen kann.
Name: CanAppendToAsync
Parameter: Guid? userId
TableRecord record
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, den bereitgestellten Datensatz anzuhängen.
Name: CanCreateAsync
Parameter: Guid? userId
TableRecord record
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz erstellen kann.
Name: CanDeleteAsync
Parameter: Guid? userId
TableRecord record
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz löschen kann.
Name: CanReadAsync
Parameter: Guid? userId
TableRecord record
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz lesen kann.
Name: CanUpdateAsync
Parameter: Guid? userId
TableRecord recordWithUpdates
TableRecord currentRecord
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer den bereitgestellten Datensatz aktualisieren kann.

IFetchXmlQueryFilterInterceptor Interface

Eigenschaften

Name
Typ
Default
Beschreibung
Tablestring
Logischer Name der Tabelle, auf die dieser Berechtigungshandler angewendet wird.
Name: Table
Typ: string
Beschreibung: Logischer Name der Tabelle, auf die dieser Berechtigungshandler angewendet wird.

Methoden

Name
Parameter
Typ
Beschreibung
CanAppendAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer einen Datensatz anhängen kann.
CanAppendToAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, einen Datensatz anzuhängen.
CanCreateAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, einen Datensatz zu erstellen.
CanDeleteAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer einen Datensatz löschen kann.
CanReadAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer einen Datensatz lesen kann.
CanUpdateAsyncGuid? userId
Task<bool>
Methode, um zu bestimmen, ob ein Benutzer einen Datensatz aktualisieren kann.
OnQueryAsyncFetchXMLBuilder fetchXmlBuilder
FetchXmlParameters parameters
Task<FetchXMLBuilder>
Aufruft, um die Änderung einer FetchXML-Abfrage vor deren Ausführung zu ermöglichen.
Name: CanAppendAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer einen Datensatz anhängen kann.
Name: CanAppendToAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, einen Datensatz anzuhängen.
Name: CanCreateAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer in der Lage sein sollte, einen Datensatz zu erstellen.
Name: CanDeleteAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer einen Datensatz löschen kann.
Name: CanReadAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer einen Datensatz lesen kann.
Name: CanUpdateAsync
Parameter: Guid? userId
Typ: Task<bool>
Beschreibung: Methode, um zu bestimmen, ob ein Benutzer einen Datensatz aktualisieren kann.
Name: OnQueryAsync
Parameter: FetchXMLBuilder fetchXmlBuilder
FetchXmlParameters parameters
Typ: Task<FetchXMLBuilder>
Beschreibung: Aufruft, um die Änderung einer FetchXML-Abfrage vor deren Ausführung zu ermöglichen.