Sichern von Anmeldeinformationen mit verknüpften Diensten mithilfe der mssparkutils

Es kommt häufig vor, dass auf Daten aus externen Quellen zugegriffen werden muss. Wenn die externe Datenquelle keinen anonymen Zugriff zulässt, müssen Sie die Verbindung wahrscheinlich mithilfe von Anmeldeinformationen, einem geheimen Schlüssel oder einer Verbindungszeichenfolge absichern.

Von Azure Synapse Analytics wird standardmäßig ein Microsoft Entra-Passthrough genutzt, um die Authentifizierung zwischen Ressourcen durchzuführen. Wenn Sie eine Verbindung zu einer Ressource mit anderen Anmeldeinformationen herstellen müssen, verwenden Sie direkt die mssparkutils. Das Paket mssparkutils vereinfacht das Abrufen von SAS-Token, Microsoft Entra-Token, Verbindungszeichenfolgen und Geheimnissen, die in einem verknüpften Dienst gespeichert sind oder sich in Azure Key Vault befinden.

Microsoft Entra ID Entra-Passthrough verwendet Berechtigungen, die Ihnen als Benutzer in Microsoft Entra ID zugewiesen sind, anstatt Berechtigungen, die Synapse oder einem separaten Dienstprinzipal zugewiesen sind. Wenn Sie z. B. Microsoft Entra-Passthrough für den Zugriff auf ein Blob in einem Speicherkonto verwenden möchten, sollten Sie zu diesem Speicherkonto wechseln und sich selbst die Rolle „Blob-Mitwirkender“ zuweisen.

Beim Abrufen von Geheimnissen aus Azure Key Vault empfehlen wir Ihnen die Erstellung eines verknüpften Diensts für Ihre Azure Key Vault-Instanz. Stellen Sie sicher, dass die verwaltete Dienstidentität (Managed Service Identity, MSI) des Synapse-Arbeitsbereichs über Berechtigungen für den Geheimnisabruf für Ihre Azure Key Vault-Instanz verfügt. Synapse führt die Authentifizierung bei Azure Key Vault mit der verwalteten Dienstidentität des Synapse-Arbeitsbereichs durch. Wenn Sie ohne verknüpften Dienst eine direkte Verbindung mit Azure Key Vault herstellen, werden für die Authentifizierung Ihre Benutzeranmeldeinformationen von Microsoft Entra verwendet.

Weitere Informationen finden Sie unter Verknüpfte Dienste.

Verwendung

mssparkutils-Hilfe für Token und Geheimnisse

Diese Funktion zeigt die Hilfedokumentation zur Verwaltung von Geheimnissen und Token in Synapse an.

mssparkutils.credentials.help()
mssparkutils.credentials.help()
Console.WriteLine(TokenLibrary.help());

Ergebnis abrufen:

 getToken(audience: String, name: String): returns AAD token for a given audience, name (optional)
 isValidToken(token: String): returns true if token hasn't expired
 getConnectionStringOrCreds(linkedService: String): returns connection string or credentials for the linked service
 getFullConnectionString(linkedService: String): returns full connection string with credentials for the linked service
 getPropertiesAll(linkedService: String): returns all the properties of the linked service
 getSecret(akvName: String, secret: String, linkedService: String): returns AKV secret for a given AKV linked service, akvName, secret key using workspace MSI
 getSecret(akvName: String, secret: String): returns AKV secret for a given akvName, secret key using user credentials
 getSecretWithLS(linkedService: String, secret: String): returns AKV secret for a given linked service, secret key
 putSecret(akvName: String, secretName: String, secretValue: String): puts AKV secret for a given akvName, secretName
 putSecret(akvName: String, secretName: String, secretValue: String, linkedService: String): puts AKV secret for a given akvName, secretName
 putSecretWithLS(linkedService: String, secretName: String, secretValue: String): puts AKV secret for a given linked service, secretName

Zugreifen auf Azure Data Lake Storage Gen2

Primärer ADLS Gen2-Speicher

Für den Zugriff auf Dateien über den primären Azure Data Lake Storage wird standardmäßig der Microsoft Entra-Passthrough für die Authentifizierung verwendet und erfordert nicht die explizite Nutzung der mssparkutils. Die in der Passthrough-Authentifizierung verwendete Identität unterscheidet sich basierend auf einigen Faktoren. Standardmäßig werden interaktive Notebooks unter Verwendung der Identität des Benutzers ausgeführt, doch kann diese in die verwaltete Dienstidentität (Managed Service Identity, MSI) des Arbeitsbereichs geändert werden. Batchaufträge und nicht interaktive Ausführungen des Notebooks verwenden die MSI des Arbeitsbereichs.

val df = spark.read.csv("abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>")
display(df.limit(10))
df = spark.read.csv('abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>')
display(df.limit(10))

ADLS Gen2-Speicher mit verknüpften Diensten

Azure Synapse Analytics verfügt über eine integrierte Funktion für verknüpfte Dienste, die für die Verbindungsherstellung mit Azure Data Lake Storage Gen2 genutzt wird. Verknüpfte Dienste können für die Authentifizierung mit einem Kontoschlüssel, Dienstprinzipal, einer verwalteten Identität oder mit Anmeldeinformationen konfiguriert werden.

Wenn für den verknüpften Dienst die Authentifizierungsmethode Kontoschlüssel festgelegt ist, wird die Authentifizierung mit dem angegebenen Speicherkontoschlüssel durchgeführt. Anschließend wird ein SAS-Schlüssel angefordert und über den Anbieter LinkedServiceBasedSASProvider automatisch auf die Speicheranforderung angewendet.

Synapse ermöglicht Benutzern das Festlegen des verknüpften Diensts für ein bestimmtes Speicherkonto. Dies ermöglicht das Lesen/Schreiben von Daten aus mehreren Speicherkonten in einer einzigen Spark-Anwendung/Abfrage. Nachdem wir spark.storage.synapse.{source_full_storage_account_name}.linkedServiceName für jedes verwendete Speicherkonto festgelegt haben, ermittelt Synapse, welcher verknüpfte Dienst für einen bestimmten Lese-/Schreibvorgang verwendet werden soll. Wenn unser Spark-Auftrag jedoch nur ein einziges Speicherkonto umfasst, können wir den Speicherkontonamen einfach weglassen und spark.storage.synapse.linkedServiceName verwenden.

val sc = spark.sparkContext
val source_full_storage_account_name = "teststorage.dfs.core.windows.net"
spark.conf.set(s"spark.storage.synapse.$source_full_storage_account_name.linkedServiceName", "<LINKED SERVICE NAME>")
sc.hadoopConfiguration.set(s"fs.azure.account.auth.type.$source_full_storage_account_name", "SAS")
sc.hadoopConfiguration.set(s"fs.azure.sas.token.provider.type.$source_full_storage_account_name", "com.microsoft.azure.synapse.tokenlibrary.LinkedServiceBasedSASProvider")

val df = spark.read.csv("abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>")

display(df.limit(10))
%%pyspark
# Set the required configs
source_full_storage_account_name = "teststorage.dfs.core.windows.net"
spark.conf.set(f"spark.storage.synapse.{source_full_storage_account_name}.linkedServiceName", "<lINKED SERVICE NAME>")
sc._jsc.hadoopConfiguration().set(f"fs.azure.account.auth.type.{source_full_storage_account_name}", "SAS")
sc._jsc.hadoopConfiguration().set(f"fs.azure.sas.token.provider.type.{source_full_storage_account_name}", "com.microsoft.azure.synapse.tokenlibrary.LinkedServiceBasedSASProvider")

# Python code
df = spark.read.csv('abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<DIRECTORY PATH>')

df.show()

Wenn die Authentifizierungsmethode für den verknüpften Dienst auf Verwaltete Identität oder Dienstprinzipal festgelegt ist, wird die verwaltete Identität oder das Dienstprinzipaltoken mit dem Anbieter LinkedServiceBasedTokenProvider verwendet.

val sc = spark.sparkContext
val source_full_storage_account_name = "teststorage.dfs.core.windows.net"
spark.conf.set(s"spark.storage.synapse.$source_full_storage_account_name.linkedServiceName", "<LINKED SERVICE NAME>")
sc.hadoopConfiguration.set(s"fs.azure.account.oauth.provider.type.$source_full_storage_account_name", "com.microsoft.azure.synapse.tokenlibrary.LinkedServiceBasedTokenProvider") 
val df = spark.read.csv("abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>")

display(df.limit(10))
%%pyspark
# Python code
source_full_storage_account_name = "teststorage.dfs.core.windows.net"
spark.conf.set(f"spark.storage.synapse.{source_full_storage_account_name}.linkedServiceName", "<LINKED SERVICE NAME>")
sc._jsc.hadoopConfiguration().set(f"fs.azure.account.oauth.provider.type.{source_full_storage_account_name}", "com.microsoft.azure.synapse.tokenlibrary.LinkedServiceBasedTokenProvider")

df = spark.read.csv('abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<DIRECTORY PATH>')

df.show()

ADLS Gen2-Speicher ohne verknüpfte Dienste

Stellen Sie mithilfe eines SAS-Schlüssels eine direkte Verbindung mit ADLS Gen2-Speicher her. Verwenden Sie ConfBasedSASProvider, und stellen Sie den SAS-Schlüssel für die Konfigurationseinstellung spark.storage.synapse.sas bereit. SAS-Token können auf Containerebene, auf Kontoebene oder global festgelegt werden. Es wird nicht empfohlen, SAS-Schlüssel auf globaler Ebene festzulegen, da der Auftrag nur Lese-/Schreibvorgänge für ein einzelnes Speicherkonto ausführen kann.

SAS-Konfiguration pro Speichercontainer

%%spark
sc.hadoopConfiguration.set("fs.azure.account.auth.type.<ACCOUNT>.dfs.core.windows.net", "SAS")
sc.hadoopConfiguration.set("fs.azure.sas.token.provider.type", "com.microsoft.azure.synapse.tokenlibrary.ConfBasedSASProvider")
spark.conf.set("spark.storage.synapse.<CONTAINER>.<ACCOUNT>.dfs.core.windows.net.sas", "<SAS KEY>")

val df = spark.read.csv("abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>")

display(df.limit(10))
%%pyspark

sc._jsc.hadoopConfiguration().set("fs.azure.account.auth.type.<ACCOUNT>.dfs.core.windows.net", "SAS")
sc._jsc.hadoopConfiguration().set("fs.azure.sas.token.provider.type", "com.microsoft.azure.synapse.tokenlibrary.ConfBasedSASProvider")
spark.conf.set("spark.storage.synapse.<CONTAINER>.<ACCOUNT>.dfs.core.windows.net.sas", "<SAS KEY>")

df = spark.read.csv('abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>')

display(df.limit(10))

SAS-Konfiguration pro Speicherkonto

%%spark
sc.hadoopConfiguration.set("fs.azure.account.auth.type.<ACCOUNT>.dfs.core.windows.net", "SAS")
sc.hadoopConfiguration.set("fs.azure.sas.token.provider.type", "com.microsoft.azure.synapse.tokenlibrary.ConfBasedSASProvider")
spark.conf.set("spark.storage.synapse.<ACCOUNT>.dfs.core.windows.net.sas", "<SAS KEY>")

val df = spark.read.csv("abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>")

display(df.limit(10))
%%pyspark

sc._jsc.hadoopConfiguration().set("fs.azure.account.auth.type.<ACCOUNT>.dfs.core.windows.net", "SAS")
sc._jsc.hadoopConfiguration().set("fs.azure.sas.token.provider.type", "com.microsoft.azure.synapse.tokenlibrary.ConfBasedSASProvider")
spark.conf.set("spark.storage.synapse.<ACCOUNT>.dfs.core.windows.net.sas", "<SAS KEY>")

df = spark.read.csv('abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>')

display(df.limit(10))

SAS-Konfiguration aller Speicherkonten

%%spark
sc.hadoopConfiguration.set("fs.azure.account.auth.type", "SAS")
sc.hadoopConfiguration.set("fs.azure.sas.token.provider.type", "com.microsoft.azure.synapse.tokenlibrary.ConfBasedSASProvider")
spark.conf.set("spark.storage.synapse.sas", "<SAS KEY>")

val df = spark.read.csv("abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>")

display(df.limit(10))
%%pyspark

sc._jsc.hadoopConfiguration().set("fs.azure.account.auth.type", "SAS")
sc._jsc.hadoopConfiguration().set("fs.azure.sas.token.provider.type", "com.microsoft.azure.synapse.tokenlibrary.ConfBasedSASProvider")
spark.conf.set("spark.storage.synapse.sas", "<SAS KEY>")

df = spark.read.csv('abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>')

display(df.limit(10))

ADLS Gen2-Speicher mit Azure Key Vault

Stellen Sie mit einem SAS-Token, das in einem Azure Key Vault-Geheimnis gespeichert ist, eine Verbindung mit ADLS Gen2-Speicher her.

%%spark
sc.hadoopConfiguration.set("fs.azure.account.auth.type", "SAS")
sc.hadoopConfiguration.set("fs.azure.sas.token.provider.type", "com.microsoft.azure.synapse.tokenlibrary.AkvBasedSASProvider")
spark.conf.set("spark.storage.synapse.akv", "<AZURE KEY VAULT NAME>")
spark.conf.set("spark.storage.akv.secret", "<SECRET KEY>")

val df = spark.read.csv("abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>")

display(df.limit(10))
%%pyspark
sc._jsc.hadoopConfiguration().set("fs.azure.account.auth.type", "SAS")
sc._jsc.hadoopConfiguration().set("fs.azure.sas.token.provider.type", "com.microsoft.azure.synapse.tokenlibrary.AkvBasedSASProvider")
spark.conf.set("spark.storage.synapse.akv", "<AZURE KEY VAULT NAME>")
spark.conf.set("spark.storage.akv.secret", "<SECRET KEY>")

df = spark.read.csv('abfss://<CONTAINER>@<ACCOUNT>.dfs.core.windows.net/<FILE PATH>')

display(df.limit(10))

TokenLibrary für andere verknüpfte Dienste

Zum Herstellen einer Verbindung mit anderen verknüpften Diensten können Sie die TokenLibrary direkt aufrufen.

getConnectionString()

Um die Verbindungszeichenfolge abzurufen, verwenden Sie die Funktion getConnectionString und übergeben den Namen des verknüpften Diensts.

%%spark
// retrieve connectionstring from mssparkutils

mssparkutils.credentials.getFullConnectionString("<LINKED SERVICE NAME>")
%%pyspark
# retrieve connectionstring from mssparkutils

mssparkutils.credentials.getFullConnectionString("<LINKED SERVICE NAME>")
%%csharp
// retrieve connectionstring from TokenLibrary

using Microsoft.Spark.Extensions.Azure.Synapse.Analytics.Utils;

string connectionString = TokenLibrary.GetConnectionString(<LINKED SERVICE NAME>);
Console.WriteLine(connectionString);

getPropertiesAll()

Die getPropertiesAll ist eine Hilfsfunktion, die in Scala und Python verfügbar ist, um alle Eigenschaften eines verknüpften Diensts abzurufen

%%pyspark
import json
# retrieve connectionstring from mssparkutils

json.loads(mssparkutils.credentials.getPropertiesAll("<LINKED SERVICE NAME>"))

Die Ausgabe sieht wie folgt aus

{
    'AuthType': 'Key',
    'AuthKey': '[REDACTED]',
    'Id': None,
    'Type': 'AzureBlobStorage',
    'Endpoint': 'https://storageaccount.blob.core.windows.net/',
    'Database': None
}

GetSecret()

Zum Abrufen eines Geheimnisses, das in Azure Key Vault gespeichert ist, empfehlen wir Ihnen die Erstellung eines verknüpften Diensts für Azure Key Vault innerhalb des Synapse-Arbeitsbereichs. Für die verwaltete Dienstidentität des Synapse-Arbeitsbereichs müssen GET-Berechtigungen gewährt werden, um Geheimnisse aus Azure Key Vault abrufen zu können. Für den verknüpften Dienst wird die verwaltete Dienstidentität genutzt, um zum Abrufen des Geheimnisses eine Verbindung mit dem Azure Key Vault-Dienst herzustellen. Ansonsten werden beim Herstellen einer direkten Verbindung mit Azure Key Vault die Microsoft Entra-Anmeldeinformationen des Benutzers verwendet. In diesem Fall müssen dem Benutzer die Berechtigungen zum Abrufen von Geheimnissen in Azure Key Vault gewährt werden.

In Government-Clouds geben Sie den vollqualifizierten Domänennamen des Schlüsseltresors an.

mssparkutils.credentials.getSecret("<AZURE KEY VAULT NAME>", "<SECRET KEY>" [, <LINKED SERVICE NAME>])

Um ein Geheimnis aus Azure Key Vault abzurufen, verwenden Sie die Funktion mssparkutils.credentials.getSecret().


mssparkutils.credentials.getSecret("<AZURE KEY VAULT NAME>", "<SECRET KEY>", "<LINKED SERVICE NAME>")

mssparkutils.credentials.getSecret("<AZURE KEY VAULT NAME>", "<SECRET KEY>", "<LINKED SERVICE NAME>")
using Microsoft.Spark.Extensions.Azure.Synapse.Analytics.Utils;

string connectionString = TokenLibrary.GetSecret("<AZURE KEY VAULT NAME>", "<SECRET KEY>", "<LINKED SERVICE NAME>");
Console.WriteLine(connectionString);

Verknüpfte Dienstverbindungen, die von der Spark-Runtime unterstützt werden

Azure Synapse Analytics unterstützt zwar eine Vielzahl von verknüpften Dienstverbindungen (aus Pipelines und anderen Azure-Produkten), aber nicht alle davon werden von der Spark-Runtime unterstützt. Hier ist die Liste der unterstützten verknüpften Dienste:

  • Azure Blob Storage
  • Azure KI Services
  • Azure Cosmos DB
  • Azure-Daten-Explorer
  • Azure Database for MySQL
  • Azure Database for PostgreSQL
  • Azure Data Lake Store (Gen1)
  • Azure-Schlüsseltresor
  • Azure Machine Learning
  • Azure Purview
  • Azure SQL-Datenbank
  • Azure SQL Data Warehouse (dediziert und serverlos)
  • Azure Storage

mssparkutils.credentials.getToken()

Wenn Sie ein OAuth-Bearertoken für den direkten Zugriff auf Dienste benötigen, können Sie die Methode getToken verwenden. Die folgenden Ressourcen werden unterstützt:

Service Name Zeichenfolgenliteral, das im API-Aufruf verwendet werden soll
Azure Storage Storage
Azure-Schlüsseltresor Vault
Azure-Verwaltung AzureManagement
Azure SQL Data Warehouse (dediziert und serverlos) DW
Azure Synapse Synapse
Azure Data Lake Store DataLakeStore
Azure Data Factory ADF
Azure-Daten-Explorer AzureDataExplorer
Azure Database for MySQL AzureOSSDB
Azure Database for MariaDB AzureOSSDB
Azure Database for PostgreSQL AzureOSSDB

Nicht unterstützter Zugriff auf verknüpfte Dienste von der Spark-Runtime aus

Die folgenden Methoden für den Zugriff auf die verknüpften Dienste werden von der Spark-Runtime nicht unterstützt:

  • Übergeben von Argumenten an einen parametrisierten verknüpften Dienst
  • Verbindungen mit benutzerseitig zugewiesenen verwalteten Identitäten (User Assigned Managed Identities, UAMI)
  • Systemseitig zugewiesene verwaltete Identitäten werden für die Keyvault-Ressource nicht unterstützt.
  • Für Azure Cosmos DB-Verbindungen wird nur der schlüsselbasierte Zugriff unterstützt. Tokenbasierter Zugriff wird nicht unterstützt.

Beim Ausführen eines Notebooks oder Spark-Auftrags können bei Anforderungen zum Abrufen eines Tokens/Geheimnisses mithilfe eines verknüpften Diensts Fehler mit der Angabe „BadRequest“ auftreten. Dies wird häufig durch ein Konfigurationsproblem mit dem verknüpften Dienst verursacht. Wenn diese Fehlermeldung angezeigt wird, überprüfen Sie die Konfiguration Ihres verknüpften Diensts. Wenn Sie Fragen haben, wenden Sie sich über das Azure-Portal an den Microsoft Azure-Support.