Proteggere le credenziali con i servizi collegati usando mssparkutils

L'accesso ai dati da origini esterne è uno schema comune. A meno che l'origine dati esterna non consenta l'accesso anonimo, è probabile che sia necessario proteggere la connessione con una credenziale, un segreto o una stringa di connessione.

Azure Synapse Analytics usa il pass-through Di Microsoft Entra per impostazione predefinita per l'autenticazione tra le risorse. Se è necessario connettersi a una risorsa usando altre credenziali, usare direttamente mssparkutils. Il pacchetto mssparkutils semplifica il processo di recupero di token di firma di accesso condiviso, token di Microsoft Entra, stringa di connessione e segreti archiviati in un servizio collegato o da un insieme di credenziali delle chiavi di Azure.

Il pass-through Di Microsoft Entra usa le autorizzazioni assegnate all'utente come utente in Microsoft Entra ID, anziché le autorizzazioni assegnate a Synapse o a un'entità servizio separata. Ad esempio, se si vuole usare il pass-through Microsoft Entra per accedere a un BLOB in un account di archiviazione, è necessario passare a tale account di archiviazione e assegnare il ruolo di collaboratore blob a se stessi.

Quando si recuperano i segreti da Azure Key Vault, è consigliabile creare un servizio collegato alla propria istanza di Azure Key Vault. Assicurarsi che l'identità del servizio gestita dell'area di lavoro di Synapse abbia privilegi Secret Get per Azure Key Vault. Synapse eseguirà l'autenticazione in Azure Key Vault usando l'identità del servizio gestita dell'area di lavoro di Synapse. Se ci si connette direttamente ad Azure Key Vault senza un servizio collegato, si eseguirà l'autenticazione usando le credenziali di Microsoft Entra dell'utente.

Per altre informazioni, vedere Servizi collegati.

Utilizzo

Guida di mssparkutils per token e segreti

Questa funzione visualizza la documentazione della Guida per la gestione dei segreti e dei token in Synapse.

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

Ottenere il risultato:

 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

Accesso a Azure Data Lake Storage Gen2

Archiviazione primaria di ADLS Gen2

L'accesso ai file dal Archiviazione azure Data Lake primario usa il pass-through Di Microsoft Entra per l'autenticazione per impostazione predefinita e non richiede l'uso esplicito di mssparkutils. L'identità usata nell'autenticazione pass-through varia in base a alcuni fattori. Per impostazione predefinita, i notebook interattivi vengono eseguiti usando l'identità dell'utente, ma possono essere modificati nell'identità del servizio gestito dell'area di lavoro. I processi batch e le esecuzioni non interattive del notebook usano l'identità del servizio gestito dell'area di lavoro.

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

Archiviazione di ADLS Gen2 con servizi collegati

Azure Synapse Analytics offre un'esperienza integrata di servizi collegati durante la connessione ad Azure Data Lake Archiviazione Gen2. I servizi collegati possono essere configurati per l'autenticazione tramite una chiave dell'account, un'entità servizio, un'identità gestita o credenziali.

Se il metodo di autenticazione del servizio collegato è impostato su Chiave dell'account, l'autenticazione verrà eseguita con la chiave dell'account di archiviazione specificata, verrà chiesta una chiave di firma di accesso condiviso che verrà automaticamente applicata alla richiesta di archiviazione tramite LinkedServiceBasedSASProvider.

Synapse consente agli utenti di impostare il servizio collegato per un account di archiviazione specifico. In questo modo è possibile leggere/scrivere dati da più account di archiviazione in un'unica applicazione Spark/query. Dopo aver impostato spark.storage.synapse.{ source_full_storage_account_name}.linkedServiceName per ogni account di archiviazione che verrà usato, Synapse individua il servizio collegato da usare per una determinata operazione di lettura/scrittura. Tuttavia, se il processo Spark gestisce solo un singolo account di archiviazione, è sufficiente omettere il nome dell'account di archiviazione e usare 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()

Se il metodo di autenticazione del servizio collegato è impostato su Identità gestita o su Entità servizio, verrà usato il token dell'identità gestita o dell'entità servizio con il provider 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()

Archiviazione di ADLS Gen2 senza servizi collegati

Connessione all'archiviazione di ADLS Gen2 direttamente usando una chiave di firma di accesso condiviso. ConfBasedSASProvider Usare e specificare la chiave di firma di accesso condiviso per l'impostazione di spark.storage.synapse.sas configurazione. I token di firma di accesso condiviso possono essere impostati a livello di contenitore, a livello di account o globale. Non è consigliabile impostare le chiavi di firma di accesso condiviso a livello globale, perché il processo non sarà in grado di leggere/scrivere da più account di archiviazione.

Configurazione della firma di accesso condiviso per ogni contenitore di archiviazione

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

Configurazione della firma di accesso condiviso per account di archiviazione

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

Configurazione della firma di accesso condiviso di tutti gli account di archiviazione

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

Archiviazione di ADLS Gen2 con Azure Key Vault

Connettersi all'archiviazione di ADLS Gen2 usando un token di firma di accesso condiviso archiviato in un segreto di 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 per altri servizi collegati

Per connettersi ad altri servizi, è possibile effettuare una chiamata diretta a TokenLibrary.

getConnectionString()

Per recuperare la stringa di connessione, usare la funzione getConnectionString e passare il nome del servizio collegato.

%%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 è una funzione helper disponibile in Scala e Python per ottenere tutte le proprietà di un servizio collegato

%%pyspark
import json
# retrieve connectionstring from mssparkutils

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

L'output sarà simile al seguente

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

GetSecret()

Per recuperare un segreto da Azure Key Vault, è consigliabile creare un servizio collegato ad Azure Key Vault all'interno dell'area di lavoro di Synapse. All'identità del servizio gestita dell'area di lavoro di Synapse sarà necessario concedere l'autorizzazione GET Secrets per Azure Key Vault. Il servizio collegato userà l'identità del servizio gestita per connettersi al servizio Azure Key Vault e recuperare il segreto. In caso contrario, la connessione diretta ad Azure Key Vault userà le credenziali di Microsoft Entra dell'utente. In questo caso, all'utente sarà necessario concedere le autorizzazioni Get Secret per Azure Key Vault.

Nei cloud per enti pubblici specificare il nome di dominio completo dell'insieme di credenziali delle chiavi.

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

Per recuperare un segreto da Azure Key Vault, usare la funzione 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);

Connessioni al servizio collegato supportate dal runtime di Spark

Anche se Azure Synapse Analytics supporta un'ampia gamma di connessioni al servizio collegato (da pipeline e altri prodotti Azure), non tutti sono supportati dal runtime di Spark. Ecco l'elenco dei servizi collegati supportati:

  • Archiviazione BLOB di Azure
  • Servizi di Azure AI
  • Azure Cosmos DB
  • Azure Data Explorer
  • Database di Azure per MySQL
  • Database di Azure per PostgreSQL
  • Azure Data Lake Store (Gen1)
  • Insieme di credenziali chiave di Azure
  • Azure Machine Learning
  • Azure Purview
  • database SQL di Azure
  • Azure SQL Data Warehouse (dedicato e serverless)
  • Archiviazione di Azure

mssparkutils.credentials.getToken()

Quando è necessario un token di connessione OAuth per accedere direttamente ai servizi, è possibile usare il getToken metodo . Sono supportate le risorse seguenti:

Nome servizio Valore letterale stringa da usare nella chiamata API
Archiviazione di Azure Storage
Insieme di credenziali chiave di Azure Vault
Gestione di Azure AzureManagement
Azure SQL Data Warehouse (dedicato e serverless) DW
Azure Synapse Synapse
Azure Data Lake Storage DataLakeStore
Azure Data Factory ADF
Esplora dati di Azure AzureDataExplorer
Database di Azure per MySQL AzureOSSDB
Database di Azure per MariaDB AzureOSSDB
Database di Azure per PostgreSQL AzureOSSDB

Accesso al servizio collegato non supportato dal runtime di Spark

I metodi seguenti per accedere ai servizi collegati non sono supportati dal runtime di Spark:

  • Passaggio di argomenti al servizio collegato con parametri
  • Connessione ions con identità gestite assegnate dall'utente
  • Le identità gestite assegnate dal sistema non sono supportate nella risorsa Keyvault
  • Per le connessioni di Azure Cosmos DB, è supportato solo l'accesso basato su chiavi. L'accesso basato su token non è supportato.

Durante l'esecuzione di un notebook o di un processo Spark, le richieste di ottenere un token/segreto usando un servizio collegato potrebbero non riuscire con un messaggio di errore che indica "BadRequest". Questo problema è spesso causato da un problema di configurazione con il servizio collegato. Se viene visualizzato questo messaggio di errore, controllare la configurazione del servizio collegato. Per eventuali domande, contattare il supporto tecnico di Microsoft Azure all'portale di Azure.