Freigeben über


Integrieren eines Drittanbietermoduls mit OneLake-Sicherheit (Vorschau)

In diesem Artikel wird beschrieben, wie Entwickler von Drittanbietermodulen die OneLake-Sicherheit integrieren können, um Daten von OneLake abzufragen und gleichzeitig die Sicherheit auf Zeilenebene (RLS) und die Sicherheit auf Spaltenebene (ClS) zu erzwingen. Die Integration verwendet das autorisierte Modulmodell, bei dem Ihr Modul Daten direkt aus OneLake liest und Sicherheitsrichtlinien in einer eigenen Computeebene erzwingt.

Hinweis

Dieses Feature ist Teil einer Preview-Version und wird nur für Evaluierungs- und Entwicklungszwecke bereitgestellt. Sie kann sich basierend auf Feedback ändern und wird nicht für den Produktionseinsatz empfohlen.

Übersicht

Die OneLake-Sicherheit definiert fein abgestimmte Zugriffssteuerungsrichtlinien – einschließlich Tabellenebene, Zeilenebene und Sicherheit auf Spaltenebene – einmal in OneLake. Microsoft Fabric-Engines wie Spark und der SQL-Analyseendpunkt setzen diese Richtlinien während der Abfrage durch. Die Sicherheit von OneLake garantiert jedoch die Durchsetzung fein abgestimmter Zugriffssteuerungsrichtlinien, unabhängig davon, wie auf die Daten zugegriffen wird. Daher werden nicht autorisierte externe Anforderungen zum Lesen von Dateien aus OneLake blockiert, um sicherzustellen, dass Daten nicht weitergegeben werden.

Das autorisierte Motorenmodell löst dieses Problem. Sie registrieren eine dedizierte Identität (Dienstprinzipal oder verwaltete Identität), die vollständigen Lesezugriff auf die Daten hat und auch die Sicherheitsmetadaten lesen kann. Ihre Engine verwendet diese Identität für:

  1. Lesen Sie die Rohdatendateien aus OneLake.
  2. Rufen Sie die effektiven Sicherheitsrichtlinien für einen bestimmten Benutzer ab, indem Sie die API Get authorized access for a principal aufrufen.
  3. Wenden Sie die zurückgegebenen Zeilen- und Spaltenfilter in einer eigenen Abfrageausführungsebene an.
  4. Gibt nur die zulässigen Daten an den Endbenutzer zurück.

Dieser Ansatz bietet Ihrem Engine die vollständige Kontrolle über die Abfrageplanung und -zwischenspeicherung, während die Durchsetzung der Sicherheitsrichtlinien mit dem übereinstimmt, was Fabric-Engines bereitstellen, und die Kontrolle über die Autorisierung in die Hände des Benutzers gelegt wird.

Voraussetzungen

Bevor Sie mit der Integration beginnen, stellen Sie sicher, dass Sie folgendes haben:

  • Ein Microsoft Entra-Dienstprinzipal oder eine verwaltete Identität, die Ihre Engine für den Zugriff auf OneLake verwendet. Nur Microsoft Entra-Identitäten werden unterstützt.
  • Rolle "Arbeitsbereichsmitglied " (oder höher) für die Modulidentität im Zielarbeitsbereich. Dadurch erhält die Identität die erforderlichen Berechtigungen zum Lesen von Datendateien und Sicherheitsmetadaten aus OneLake.
  • Ein Fabric-Element (Lakehouse, gespiegelte Datenbank oder gespiegelter Katalog) mit aktivierter OneLake-Sicherheit.
  • OneLake-Sicherheitsrollen, die für das Element mit allen RLS- oder CLS-Richtlinien konfiguriert sind, die Sie erzwingen möchten.
  • Die Modulidentität muss uneingeschränkten Lesezugriff auf die von ihr gelesenen Tabellen haben. Wenn RLS- oder CLS-Richtlinien für die Engine-Identität selbst gelten, geben API-Aufrufe Fehler zurück.

Architektur

Das folgende Diagramm zeigt den übergeordneten Autorisierungsfluss für eine autorisierte Engine-Integration.

┌──────────────┐       ┌──────────────────┐       ┌───────────┐
│  End user    │──1──▶│  3rd-party engine │──2──▶│  OneLake  │
│  (query)     │       │(service principal)│◀──3──│  (data +  │
│              │◀──6──│                   │──4──▶│  security)│
└──────────────┘       └──────────────────┘       └───────────┘
  1. Der Endbenutzer sendet eine Abfrage an das Drittanbietermodul.
  2. Die Engine-Identität authentifiziert sich bei OneLake und liest die Rohdatendateien (Delta Parquet) mithilfe von OneLake-APIs.
  3. OneLake gibt die angeforderten Daten zurück.
  4. Das Modul ruft die API auf und übergibt die principalAccess Microsoft Entra-Objekt-ID des Endbenutzers, um den effektiven Zugriff des Benutzers zu erhalten.
  5. Das Modul wendet die zurückgegebenen Zugriffsfilter (Tabellenzugriff, RLS-Prädikate, CLS-Spaltenlisten) auf die Daten in einer eigenen Computeebene an.
  6. Das Modul gibt nur die gefilterten, zulässigen Ergebnisse an den Endbenutzer zurück.

Schritt 1: Einrichten der Engine-Identität

Ihr Engine benötigt eine Microsoft Entra Identität, die OneLake anerkennt und vertraut. Diese Identität liest Datendateien und Sicherheitsmetadaten im Auftrag Ihrer Engine.

  1. Erstellen oder identifizieren Sie einen Dienstprinzipal oder eine verwaltete Identität in Microsoft Entra ID für Ihre Engine. Weitere Informationen finden Sie unter Anwendungs- und Dienstprinzipalobjekte in Microsoft Entra ID.

  2. Fügen Sie der Arbeitsbereichsmitgliedsrolle die Identität hinzu. Wechseln Sie im Fabric-Portal zu den Arbeitsbereichseinstellungen und fügen Sie der Member-Rolle den Dienstprinzipal hinzu. Dadurch wird die Identität gewährt:

    • Lesezugriff auf alle Datendateien in OneLake für Elemente in diesem Arbeitsbereich.
    • Zugriff auf OneLake-Sicherheitsrollenmetadaten über die autorisierten Engine-APIs.

    Weitere Informationen zu Arbeitsbereichsrollen finden Sie unter Rollen in Arbeitsbereichen.

  3. Stellen Sie sicher, dass die Identität uneingeschränkten Zugriff hat. Die Engine-Identität muss über vollständigen Lesezugriff auf jede Tabelle verfügen, nach der sie Abfragen durchführt. Wenn eine oneLake-Sicherheitsrolle RLS- oder CLS-Einschränkungen auf die Modulidentität anwendet, schlagen Datenlesevorgänge und API-Aufrufe fehl. Die beste Praxis besteht darin, die Engine-Identität keiner OneLake-Sicherheitsrollen hinzuzufügen, die RLS- oder CLS-Einschränkungen enthalten.

Von Bedeutung

Sie können den Zugriff der Engine jederzeit widerrufen, indem Sie sie aus der Arbeitsbereichsrolle entfernen. Das Widerrufen des Zugriffs wird innerhalb von ungefähr 2 Minuten wirksam.

Schritt 2: Lesen von Daten aus OneLake

Mit der konfigurierten Modulidentität kann Ihr Modul Datendateien direkt aus OneLake mithilfe der standardmäßigen azure Data Lake Storage (ADLS) Gen2-kompatiblen APIs lesen.

Auf OneLake-Daten kann zugegriffen werden unter:

https://onelake.dfs.fabric.microsoft.com/{workspaceId}/{itemId}/Tables/{schema}/{tableName}/

Ihr Modul authentifiziert sich mit einem Bearertoken, das über den Microsoft Entra OAuth 2.0-Clientanmeldeinformationsfluss abgerufen wurde. Verwenden Sie den OneLake-Ressourcenbereich https://storage.azure.com/.default beim Anfordern des Tokens.

Beispiel: Authentifizieren und Lesen von Daten (Python)

from azure.identity import ClientSecretCredential
from azure.storage.filedatalake import DataLakeServiceClient

tenant_id = "<your-tenant-id>"
client_id = "<your-service-principal-client-id>"
client_secret = "<your-service-principal-secret>"

credential = ClientSecretCredential(tenant_id, client_id, client_secret)

service_client = DataLakeServiceClient(
    account_url="https://onelake.dfs.fabric.microsoft.com",
    credential=credential
)

# Access a specific item in a workspace
file_system_client = service_client.get_file_system_client("<workspace-id>")
directory_client = file_system_client.get_directory_client("<item-id>/Tables/dbo/Customers")

# List and read Delta parquet files
for path in directory_client.get_paths():
    if path.name.endswith(".parquet"):
        file_client = file_system_client.get_file_client(path.name)
        downloaded = file_client.download_file()
        data = downloaded.readall()
        # Process the parquet data with your engine

Weitere Informationen zu OneLake-APIs finden Sie unter OneLake-Zugriff mit APIs.

Schritt 3: Abrufen des effektiven Zugriffs des Benutzers

Nach dem Lesen der Rohdaten muss das Modul bestimmen, was der Abfragebenutzer sehen darf. Rufen Sie die API Get authorized access for a principal auf, um den effektiven Zugriff des Benutzers auf das Element zu ermitteln.

API-Endpunkt

GET https://onelake.dfs.fabric.microsoft.com/v1.0/workspaces/{workspaceId}/artifacts/{artifactId}/securityPolicy/principalAccess

Anforderungstext

{
  "aadObjectId": "<end-user-entra-object-id>",
  "inputPath": "Tables",
  "maxResults": 500 //optional, default is 500
}
Parameter Typ Erforderlich Beschreibung
aadObjectId Schnur Ja Die Microsoft Entra-Objekt-ID des Endbenutzers, dessen Zugriff Sie überprüfen möchten.
inputPath Schnur Ja Entweder Tables oder Files. Gibt den Zugriff des Benutzers für den angegebenen Abschnitt des Elements zurück. Für die meisten Abfragemodule lautet der inputPath -Parameter Tables.
Fortsetzungs-Token Schnur No Wird verwendet, um fortgesetzte Ergebnisse abzurufen, wenn die Ergebnismenge maxResults übersteigt.
maxResults Integer No Maximale Anzahl von Elementen pro Seite. Der Standardwert ist 500.

Beispielantwort (nur RLS)

{
  "identityETag": "3fc4dc476ded773e4cf43936190bf20fa9480a077b25edc0b4bbe247112542f6",
  "metadataETag": "\"eyJhciI6IlwiMHg4R...\"",
  "value": [
    {
      "path": "Tables/dbo/Customers",
      "access": ["Read"],
      "rows": "SELECT * FROM [dbo].[Customers] WHERE [customerId] = '123'",
      "effect": "Permit"
    },
    {
      "path": "Tables/dbo/Employees",
      "access": ["Read"],
      "rows": "SELECT * FROM [dbo].[Employees] WHERE [address] = '123'",
      "effect": "Permit"
    },
    {
      "path": "Tables/dbo/EmployeeTerritories",
      "access": ["Read"],
      "effect": "Permit"
    }
  ]
}

Beispielantwort (RLS und CLS)

Wenn die Sicherheit auf Spaltenebene in einer Tabelle konfiguriert ist, enthält die Antwort ein columns Array, das nur die Spalten auflistet, auf die der Benutzer zugreifen darf. Spalten, die in diesem Array nicht vorhanden sind, werden vom Benutzer ausgeblendet.

{
  "identityETag": "79372bc169b00882d9abec3d404032131e96bc406e15c6766514723021e153eb",
  "metadataETag": "\"eyJhciI6IlwiMHg4R...\"",
  "value": [
    {
      "path": "Tables/dbo/Customers",
      "access": ["Read"],
      "columns": [
        {
          "name": "address",
          "columnEffect": "Permit",
          "columnAction": ["Read"]
        },
        {
          "name": "city",
          "columnEffect": "Permit",
          "columnAction": ["Read"]
        },
        {
          "name": "contactTitle",
          "columnEffect": "Permit",
          "columnAction": ["Read"]
        },
        {
          "name": "country",
          "columnEffect": "Permit",
          "columnAction": ["Read"]
        },
        {
          "name": "fax",
          "columnEffect": "Permit",
          "columnAction": ["Read"]
        },
        {
          "name": "phone",
          "columnEffect": "Permit",
          "columnAction": ["Read"]
        },
        {
          "name": "postalCode",
          "columnEffect": "Permit",
          "columnAction": ["Read"]
        },
        {
          "name": "region",
          "columnEffect": "Permit",
          "columnAction": ["Read"]
        }
      ],
      "rows": "SELECT * FROM [dbo].[Customers] WHERE [customerID] = 'ALFKI'",
      "effect": "Permit"
    },
    {
      "path": "Tables/dbo/Employees",
      "access": ["Read"],
      "rows": "SELECT * FROM [dbo].[Employees] WHERE [address] = '123'",
      "effect": "Permit"
    }
  ]
}

Verständnis der Antwort

Die Antwort enthält ein Array von PrincipalAccessEntry Objekten, die jeweils eine Tabelle darstellen, auf die der Benutzer Zugriff hat. Auf Tabellen, die in der Antwort nicht vorhanden sind, kann der Benutzer nicht zugreifen.

Feld Typ Beschreibung
path Schnur Der Pfad zur Tabelle, auf die der Benutzer zugreifen kann, z. B Tables/dbo/Customers. .
access string[] Das Array der gewährten Zugriffstypen. Derzeit wird nur Read unterstützt.
columns Objekt[] Ein Array von Spaltenobjekten, auf die der Benutzer zugreifen darf. Jedes Objekt enthält name (Spaltenname), columnEffect (Permit) und columnAction (["Read"]). Wenn dieses Feld nicht vorhanden ist, gilt keine CLS, und alle Spalten sind zulässig. Wenn vorhanden, sollten nur die aufgelisteten Spalten zurückgegeben werden.
rows Schnur Eine T-SQL-Anweisung SELECT , die den Sicherheitsfilter auf Zeilenebene darstellt. Nur Zeilen, die diesem Prädikat entsprechen, sollten an den Benutzer zurückgegeben werden. Wenn dieses Feld nicht vorhanden ist, gilt kein RLS, und alle Zeilen sind zulässig.
effect Schnur Der Effekttyp. Aktuell immer Permit.

Von Bedeutung

Das rows Feld enthält einen T-SQL-Ausdruck, den das Modul analysieren und als Filter-Prädikat anwenden muss. Der Ausdruck verwendet ein SELECT * FROM [schema].[table] WHERE ... Format. Ihr Modul muss die WHERE Klausel extrahieren und auf die zurückgegebenen Daten anwenden.

ETags zum Zwischenspeichern

Die Antwort enthält zwei ETag-Werte, die eine effiziente Zwischenspeicherung ermöglichen:

  • identityETag: Stellt den aktuellen Status der Identitäts- und Gruppenmitgliedschaften des Benutzers dar. Speichern Sie das Zugriffsergebnis des Benutzers, und verwenden Sie es erneut, bis sich dieses ETag ändert.
  • metadataETag: Stellt den aktuellen Status der Sicherheitskonfiguration des Elements dar. Cache-Rollen-Metadaten zwischen und verwende diese erneut, bis sich das ETag ändert.

Verwenden Sie diese ETags mit dem If-None-Match Anforderungsheader, um das erneute Abrufen von unveränderten Daten zu vermeiden. Dadurch wird die Leistung für Mehrbenutzercaches verbessert.

Beispiel: Abrufen eines effektiven Zugriffs (Python)

import requests

# Get a token for the OneLake DFS endpoint
token = credential.get_token("https://storage.azure.com/.default").token

workspace_id = "<workspace-id>"
artifact_id = "<artifact-id>"
user_object_id = "<end-user-entra-object-id>"

url = (
    f"https://onelake.dfs.fabric.microsoft.com/v1.0/"
    f"workspaces/{workspace_id}/artifacts/{artifact_id}/"
    f"securityPolicy/principalAccess"
)

headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json"
}

body = {
    "aadObjectId": user_object_id,
    "inputPath": "Tables"
}

response = requests.get(url, headers=headers, json=body)
access_data = response.json()

# The response contains the user's effective access
for entry in access_data["value"]:
    print(f"Table: {entry['path']}, Access: {entry['access']}")
    if "columns" in entry:
        col_names = [col["name"] for col in entry["columns"]]
        print(f"  CLS permitted columns: {col_names}")
    if "rows" in entry:
        print(f"  RLS filter: {entry['rows']}")

Schritt 4: Anwenden von Sicherheitsfiltern

Nach dem Abrufen des effektiven Zugriffs des Benutzers muss Ihr Modul die Sicherheitsrichtlinien auf die Daten anwenden, bevor Ergebnisse zurückgegeben werden. Dieser Schritt ist wichtig – Ihr Modul ist dafür verantwortlich, die Richtlinien ordnungsgemäß zu erzwingen.

Filterung auf Tabellenebene

Gibt nur Daten aus Tabellen zurück, die in der principalAccess Antwort angezeigt werden. Wenn eine Tabelle nicht aufgeführt ist, hat der Benutzer keinen Zugriff darauf, und es sollten keine Daten zurückgegeben werden.

# Build a set of accessible tables for the user
accessible_tables = {entry["path"] for entry in access_data["value"]}

# Before returning query results, verify the table is accessible
def is_table_accessible(table_path: str) -> bool:
    return table_path in accessible_tables

Sicherheitsfilter auf Zeilenebene

Wenn ein rows Feld in einem Zugriffseintrag vorhanden ist, muss das Modul das T-SQL-Prädikat analysieren und als Filter auf die Daten der Tabelle anwenden. Der rows Wert ist eine SELECT Anweisung mit einer WHERE Klausel, die definiert, welche Zeilen der Benutzer sehen kann.

Von Bedeutung

Wenn das Modul SQL-Anweisungen nicht analysieren kann, sollten Abfragen für Tabellen mit einer Nicht-Null-Eigenschaft rows mit einem Fehler fehlschlagen und keine Daten zurückgeben. Dadurch wird sichergestellt, dass Benutzern nur Zugriff auf das gewährt wird, was sie sehen dürfen.

Beispielsweise der folgende RLS-Filter:

SELECT * FROM [dbo].[Customers] WHERE [customerId] = '123' UNION SELECT * FROM [dbo].[Customers] WHERE [customerID] = 'ALFKI'

Ihr Modul sollte die Prädikate extrahieren und anwenden, um die Daten zu filtern:

import sqlparse

def extract_rls_predicates(rls_expression: str) -> list:
    """
    Parse the RLS T-SQL expression and extract WHERE clause predicates.
    The expression may contain UNION of multiple SELECT statements.
    """
    predicates = []
    statements = rls_expression.split(" UNION ")
    for stmt in statements:
        parsed = sqlparse.parse(stmt)[0]
        where_seen = False
        where_clause = []
        for token in parsed.tokens:
            if where_seen:
                where_clause.append(str(token).strip())
            if token.ttype is sqlparse.tokens.Keyword and token.value.upper() == "WHERE":
                where_seen = True
        if where_clause:
            predicates.append(" ".join(where_clause))
    return predicates


def apply_rls_filter(dataframe, access_entry: dict):
    """Apply RLS filtering to a dataframe based on the access entry."""
    if "rows" not in access_entry:
        return dataframe  # No RLS, return all rows

    predicates = extract_rls_predicates(access_entry["rows"])
    # Combine predicates with OR (UNION semantic)
    combined_filter = " OR ".join(f"({p})" for p in predicates)
    return dataframe.filter(combined_filter)

Von Bedeutung

Wenn das rows Feld bei einem Zugriffseintrag nicht vorhanden ist, gilt kein RLS für diese Tabelle, und alle Zeilen sollten zurückgegeben werden. Wenn das Feld vorhanden ist, muss Ihre Engine die Daten filtern. Das Zurückgeben ungefilterter Daten für eine Tabelle mit RLS ist eine Sicherheitsverletzung.

Sicherheitsfilter auf Spaltenebene

Wenn CLS in einer Tabelle konfiguriert ist, enthält die principalAccess Antwort ein columns Array, das die Spalten explizit auflistet, auf die der Benutzer zugreifen darf. Jedes Spaltenobjekt enthält:

Eigentum Typ Beschreibung
name Schnur Der Spaltenname (Groß- und Kleinschreibung beachten).
columnEffect Schnur Der Effekt, der auf die Spalte angewendet wurde. Aktuell immer Permit.
columnAction string[] Die für die Spalte zulässigen Aktionen. Derzeit wird nur Read unterstützt.

Wenn das columns Feld bei einem Zugriffseintrag nicht vorhanden ist, gilt keine CLS, und alle Spalten in der Tabelle sind zulässig. Wenn das columns Feld vorhanden ist, muss das Modul nur die aufgelisteten Spalten zurückgeben.

def get_permitted_columns(access_entry: dict) -> list | None:
    """
    Return the list of permitted column names for a table.
    Returns None if no CLS applies (all columns are permitted).
    """
    if "columns" not in access_entry:
        return None  # No CLS, all columns are permitted

    return [
        col["name"]
        for col in access_entry["columns"]
        if col.get("columnEffect") == "Permit"
        and "Read" in col.get("columnAction", [])
    ]


def apply_cls_filter(dataframe, access_entry: dict):
    """Apply CLS filtering to a dataframe based on the access entry."""
    permitted_columns = get_permitted_columns(access_entry)
    if permitted_columns is None:
        return dataframe  # No CLS, return all columns

    # Only keep columns that are in the permitted list
    return dataframe.select(permitted_columns)

Von Bedeutung

Wenn das columns Feld bei einem Zugriffseintrag nicht vorhanden ist, wird keine CLS angewendet, und alle Spalten sollten zurückgegeben werden. Wenn das Feld vorhanden ist, darf das Modul nur die aufgelisteten Spalten zurückgeben. Das Zurückgeben ausgeblendeter Spalten ist eine Sicherheitsverletzung.

Behandeln von Tabellen ohne Zugriff

Wenn ein Benutzer eine Tabelle abfragt, die nicht in der principalAccess Antwort angezeigt wird, muss ihr Modul den Zugriff verweigern. Verzichten Sie darauf, ungefilterte Daten zurückzugeben.

def query_table(table_path: str, user_access: dict):
    """Query a table with OneLake security enforcement."""
    # Find the user's access entry for this table
    entry = next(
        (e for e in user_access["value"] if e["path"] == table_path),
        None
    )

    if entry is None:
        raise PermissionError(
            f"Access denied: user doesn't have permission to access {table_path}"
        )

    # Read the data from OneLake
    data = read_table_from_onelake(table_path)

    # Apply column-level security
    data = apply_cls_filter(data, entry)

    # Apply row-level security
    data = apply_rls_filter(data, entry)

    return data

Schritt 5: Behandeln der Zwischenspeicherung und Änderungserkennung

Für Integrationen auf Produktionsniveau, insbesondere für Engines mit mehrbenutzerfähigen Caches, müssen Sie Änderungen an Sicherheitsrichtlinien und Benutzergruppenmitgliedschaften handhaben.

Cachesicherheitsmetadaten

Verwenden Sie die identityETag Werte und metadataETag Werte aus der principalAccess Antwort, um zu bestimmen, wann zwischengespeicherte Sicherheitsinformationen veraltet sind:

  • identityETag: Änderungen, wenn die Gruppenmitgliedschaften oder Identitätseigenschaften des Benutzers aktualisiert werden. Zwischenspeichern Sie den effektiven Zugriff des Benutzers, der auf (userId, identityETag) basiert.
  • metadataETag: Änderungen, wenn die OneLake-Sicherheitsrollen oder -richtlinien für das Element aktualisiert werden. Zwischenspeicher-Rollendefinitionen, die unter Verwendung von (artifactId, metadataETag) indiziert sind.

Abfragen von Änderungen

principalAccess Die API wird regelmäßig abgerufen, um Änderungen zu erkennen. Die API sollte vor der Abfrageausführung abgefragt werden, um sicherzustellen, dass sich nichts geändert hat, anstatt ergebnisse direkt aus dem Cache zu verarbeiten. Verwenden Sie den If-None-Match Header mit dem zuvor empfangenen ETag Header, um die Bandbreite zu minimieren:

headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json",
    "If-None-Match": f'"{cached_etag}"'
}

response = requests.get(url, headers=headers, json=body)

if response.status_code == 304:
    # Security hasn't changed, use cached data
    pass
elif response.status_code == 200:
    # Security has changed, update cache
    new_access_data = response.json()
    update_cache(user_id, new_access_data)

Überlegungen zur Latenz

  • Änderungen an OneLake-Sicherheitsrollendefinitionen dauern etwa 5 Minuten , bis sie verteilt werden.
  • Änderungen an Benutzergruppenmitgliedschaften in Microsoft Entra ID dauern ca. 1 Stunde, bis sie in OneLake widerspiegelt.
  • Einige Fabric-Engines verfügen über eine eigene Zwischenspeicherungsebene, daher ist möglicherweise zusätzliche Zeit erforderlich.

Gestalten Sie Ihr Abrufintervall und die Cache-TTL entsprechend. Ein empfohlener Ansatz ist es, jede 5 Minuten nach Änderungen von Sicherheitsmetadaten abzufragen und benutzerspezifischen Zugriff bei jeder Abfrage oder in einem kürzeren Intervall zu aktualisieren.

Schritt 6: Verwalten der Paginierung

Die principalAccess API unterstützt die Paginierung für Elemente mit vielen Tabellen. Wenn die Antwort mehr Einträge enthält als maxResults, enthält die Antwort eine continuationToken.

all_entries = []
continuation_token = None

while True:
    body = {
        "aadObjectId": user_object_id,
        "inputPath": "Tables",
        "maxResults": 500
    }
    if continuation_token:
        body["continuationToken"] = continuation_token

    response = requests.get(url, headers=headers, json=body)
    data = response.json()
    all_entries.extend(data["value"])

    # Check for continuation token in response
    continuation_token = data.get("continuationToken")
    if not continuation_token:
        break

Fehlerbehandlung

Behandeln Sie die folgenden Fehlerszenarien in Ihrer Integration:

HTTP-Status Fehlercode Beschreibung Empfohlene Maßnahme
200 - Erfolg. Verarbeiten sie die Antwort.
404 ElementNichtGefunden Der Arbeitsbereich oder das Element besteht nicht, oder die Engine-Identität hat keinen Zugriff. Überprüfen Sie die Arbeitsbereichs-ID und artefakt-ID. Vergewissern Sie sich, dass die Engine-Identität über Zugriff für Arbeitsbereichsmitglieder verfügt.
412 Vorbedingung fehlgeschlagen Das bereitgestellte ETag If-Match stimmt nicht mit dem aktuellen Ressourcen-ETag überein. Rufen Sie die Ressource ohne den If-Match Header erneut ab, um das neueste ETag abzurufen.
429 - Die Ratebegrenzung wurde überschritten. Warten Sie auf die in der Retry-After Kopfzeile angegebene Dauer, bevor Sie den Vorgang wiederholen.

Bewährte Methoden für die Sicherheit

Befolgen Sie die folgenden bewährten Methoden, um eine sichere Integration sicherzustellen:

  • Schützen Sie die Anmeldeinformationen für die Engine-Identität. Der Dienstprinzipal hat erhöhten Zugriff auf Daten in OneLake. Speichern Sie Anmeldeinformationen sicher mithilfe von Diensten wie Azure Key Vault.
  • Keine Rohdaten für Endbenutzer verfügbar machen. Wenden Sie immer die von der principalAccess API zurückgegebenen Sicherheitsfilter an, bevor Sie Daten zurückgeben. Das Umgehen der Durchsetzung ist ein Sicherheitsverstoß.
  • Überprüfen Sie RLS-Prädikate sorgfältig. Analysieren und wenden Sie die T-SQL-Klausel WHERE Prädikate genau an. Falsche Analyse kann zu Datenlecks führen. Treten Analysefehler oder unsichere Syntaxzuordnungen auf, soll die Abfrage mit einem RLS-Analysefehler fehlschlagen, anstatt dem Benutzer unvollständige oder unsichere Ergebnisse zu präsentieren.
  • Fehlende Tabellen wie Zugang verweigert behandeln. Wenn eine Tabelle in der API-Antwort nicht vorhanden ist, hat der Benutzer keinen Zugriff. Greifen Sie niemals auf ungefilterte Daten zurück, die OneLake-Sicherheit verwendet standardmäßig die Einstellung "Ablehnen".
  • Überwachen des Zugriffs. Protokollieren Sie, welche Benutzer auf welche Tabellen zugreifen und welche Sicherheitsrichtlinien für Compliance und Problembehandlung angewendet wurden.
  • Prüfen auf Sicherheitsänderungen. Verwenden Sie ETags, um Änderungen zu erkennen und zwischengespeicherte Richtlinien umgehend zu aktualisieren.

Einschränkungen

  • Die principalAccess API befindet sich in der Vorschau und kann sich je nach Feedback ändern.
  • Der Read Zugriffstyp und der Permit Effekt werden aktuell unterstützt.
  • Die Engine-Identität muss über uneingeschränkten Root-Zugriff verfügen. Wenn RLS oder CLS auf die Modulidentität angewendet wird, schlagen API-Aufrufe fehl.
  • RLS-Prädikate verwenden T-SQL-Syntax. Ihre Engine ist dafür verantwortlich, die Prädikate richtig zu parsen und anzuwenden.
  • Änderungen der Sicherheitsrichtlinien dauern ungefähr 5 Minuten, um sich zu verbreiten. Änderungen der Benutzergruppenmitgliedschaft dauern ungefähr 1 Stunde.