Sécuriser les informations d’identification avec les services liés à l’aide de mssparkutils

L’accès aux données de sources externes est un modèle courant. À moins que la source de données externe autorise l’accès anonyme, il est probable que vous aurez besoin de sécuriser votre connexion avec des informations d’identification, un secret ou une chaîne de connexion.

Azure Synapse Analytics utilise le transfert direct de Microsoft Entra par défaut pour l’authentification entre les ressources. Si vous devez vous connecter à une ressource avec d’autres informations d’identification, utilisez directement mssparkutils. Le package mssparkutils simplifie le processus de récupération des jetons SAS, des jetons Microsoft Entra, des chaînes de connexion et des secrets stockés dans un service lié ou dans un coffre de clés Azure.

L’authentification directe Microsoft Entra utilise les autorisations qui vous sont attribuées en tant qu’utilisateur dans Microsoft Entra ID, plutôt que les autorisations attribuées à Synapse ou à un principal de service distinct. Par exemple, si vous souhaitez utiliser l’authentification directe Microsoft Entra pour accéder à un blob dans un compte de stockage, vous devez accéder à ce compte de stockage et vous attribuer le rôle contributeur d’objet blob.

Lorsque vous récupérez des secrets à partir d’Azure Key Vault, nous vous conseillons de créer un service lié à votre coffre de clés Azure. Vérifiez que les identités managées pour les ressources Azure de l’espace de travail Synapse disposent des privilèges Secret Get sur votre coffre de clés Azure. Synapse s’authentifie auprès d’Azure Key Vault au moyen des identités managées pour les ressources Azure de l’espace de travail Synapse. Si vous vous connectez directement à Azure Key Vault sans service lié, vous devez vous authentifier avec vos informations d’identification d’utilisateur Microsoft Entra.

Pour plus d’informations, consultez services liés.

Usage

Aide sur mssparkutils pour les jetons et les secrets

Cette fonction affiche la documentation d’aide pour la gestion des secrets et des jetons dans Synapse.

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

Vous obtenez le résultat suivant :

 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

Accès à Azure Data Lake Storage Gen2

Stockage principal ADLS Gen2

L’accès aux fichiers depuis l’instance principale de Azure Data Lake Storage utilise l’authentification directe de Microsoft Entra pour l’authentification par défaut, et n’a pas besoin de l’utilisation explicite de mssparkutils. L’identité utilisée pour l’authentification directe varie selon certains facteurs. Par défaut, les notebooks interactifs sont exécutés à l’aide de l’identité de l’utilisateur, mais ils peuvent être modifiés en identité du service géré (MSI) de l’espace de travail. Les programmes de traitement par lots et les exécutions non interactives du notebook utilisent le MSI de l’espace de travail.

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

Stockage ADLS Gen2 avec les services liés

Azure Synapse Analytics propose une expérience de services liés intégrée lors de la connexion à Azure Data Lake Storage Gen2. Les services liés peuvent être configurés pour s’authentifier à l’aide d’une clé de compte, d’un principal de service, d’une identité managée ou d’informations d’identification.

Lorsque la méthode d’authentification du service lié est définie sur Clé de compte, le service lié s’authentifie au moyen de la clé de compte de stockage fournie, il demande une clé SAS et l’applique automatiquement à la requête de stockage à l’aide de LinkedServiceBasedSASProvider.

Synapse permet aux utilisateurs de définir le service lié pour un compte de stockage particulier. Il est ainsi possible de lire/écrire des données provenant de différents comptes de stockage dans une même requête/application Spark. Une fois spark.storage.synapse.{source_full_storage_account_name}.linkedServiceName défini pour chacun des comptes de stockage à utiliser, Synapse détermine le service lié à utiliser pour une opération de lecture/écriture particulière. Toutefois, si le travail Spark ne traite qu’un seul compte de stockage, il est possible d’omettre le nom du compte de stockage et d’utiliser spark.storage.synapse.linkedServiceName.

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

Lorsque la méthode d’authentification du service lié est définie sur Identité managée ou Principal du service, le service lié utilise l’identité managée ou le jeton du principal du service avec le fournisseur LinkedServiceBasedTokenProvider.

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

Stockage ADLS Gen2 sans service lié

Connectez-vous directement au stockage ADLS Gen2 avec une clé SAS. Utilisez ConfBasedSASProvider et fournissez la clé SAS au paramètre de configuration spark.storage.synapse.sas. Des jetons SAS peuvent être définis au niveau du conteneur, au niveau du compte ou globalement. Nous vous déconseillons de définir des clés SAS au niveau global, car le travail ne peut pas lire/écrire à partir de plusieurs comptes de stockage.

Configuration SAS par conteneur de stockage

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

Configuration SAS par compte de stockage

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

Configuration SAS de tous les comptes de stockage

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

Stockage ADLS Gen2 avec Azure Key Vault

Connectez-vous au stockage ADLS Gen2 à l’aide d’un jeton SAS stocké dans le secret Azure Key Vault.

%%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 pour d’autres services liés

Pour vous connecter à d’autres services liés, vous pouvez effectuer un appel direct à TokenLibrary.

getConnectionString()

Pour récupérer la chaîne de connexion, utilisez la fonction getConnectionString et transmettez le nom du service lié.

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

getPropertiesAll est une fonction d’aide disponible dans Scala et Python permettant d’obtenir toutes les propriétés d’un service lié

%%pyspark
import json
# retrieve connectionstring from mssparkutils

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

La sortie se présentera ainsi

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

GetSecret()

Pour récupérer un secret stocké depuis Azure Key Vault, nous vous recommandons de créer un service lié à Azure Key Vault au sein de l’espace de travail Synapse. L’autorisation GET Secrets au coffre de clés Azure devra être accordée aux identités managées pour les ressources Azure de l’espace de travail Synapse. Le service lié utilisera les identités managées pour les ressources Azure afin de se connecter au service Azure Key Vault et de récupérer le secret. Sinon, la connexion directe à Azure Key Vault utilisera les informations d’identification de l’utilisateur Microsoft Entra. Dans ce cas, l’utilisateur devra disposer des autorisations Get Secret dans Azure Key Vault.

Dans les clouds du gouvernement, fournissez le nom de domaine complet du coffre de clés.

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

Pour récupérer un secret à partir d’Azure Key Vault, utilisez la fonction 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);

Connexions de service lié prises en charge à partir du runtime Spark

Bien qu’Azure Synapse Analytics prenne en charge une variété connexions de service lié (à partir de pipelines et d’autres emplacements), toutes ne sont pas prises en charge à partir du runtime Spark. Voici la liste des services liés pris en charge :

  • Stockage Blob Azure
  • Azure AI services
  • Azure Cosmos DB
  • Explorateur de données Azure
  • Azure Database pour MySQL
  • Azure Database pour PostgreSQL
  • Azure Data Lake Store (Gen1)
  • Azure Key Vault
  • Azure Machine Learning
  • Azure Purview
  • Azure SQL Database
  • Azure SQL Data Warehouse (dédié et sans serveur)
  • Stockage Azure

mssparkutils.credentials.getToken()

Lorsque vous avez besoin d’un jeton de porteur OAuth pour accéder directement aux services, vous pouvez utiliser la getToken méthode . Les ressources suivantes sont prises en charge :

Nom du service Littéral de chaîne à utiliser dans l’appel d’API
Stockage Azure Storage
Azure Key Vault Vault
Gestion d’Azure AzureManagement
Azure SQL Data Warehouse (dédié et sans serveur) DW
Azure Synapse Synapse
Azure Data Lake Store DataLakeStore
Azure Data Factory ADF
Explorateur de données Azure AzureDataExplorer
Azure Database pour MySQL AzureOSSDB
Azure Database for MariaDB AzureOSSDB
Azure Database pour PostgreSQL AzureOSSDB

Accès au service lié non pris en charge à partir du runtime Spark

Les méthodes suivantes pour accéder aux services liés ne sont pas prises en charge à partir du runtime Spark :

  • Passage d’arguments au service lié paramétrable
  • Connexions portant des identités gérées attribuées aux utilisateurs (UAMI)
  • Les identités managées affectées par le système ne sont pas prises en charge sur la ressource Keyvault
  • Pour les connexions Azure Cosmos DB, seul l’accès en fonction de la clé est pris en charge. L’accès en fonction d’un jeton n’est pas pris en charge.

Quand vous exécutez un notebook ou un travail Spark, les demandes d’obtention d’un jeton/secret en utilisant un service lié peuvent échouer avec un message d’erreur indiquant « BadRequest ». Cela est souvent dû à un problème de configuration avec le service lié. Si vous voyez ce message d’erreur, vérifiez la configuration de votre service lié. Si vous avez des questions, contactez le support Microsoft Azure sur le Portail Azure.