Esercitazione: Connessione ai database di Azure da servizio app senza segreti usando un'identità gestita
Articolo
Il Servizio app fornisce un servizio di hosting Web ad alta scalabilità e con funzioni di auto-correzione in Azure. Fornisce anche un'identità gestita per l'app, che è una soluzione chiave per proteggere l'accesso ai database di Azure, tra cui:
Le identità gestite nel servizio app rendono l'app più sicura eliminando i segreti dall'app, ad esempio le credenziali nelle stringhe di connessione. Questa esercitazione illustra come connettersi ai database menzionati in precedenza da servizio app usando identità gestite.
Contenuto dell'esercitazione:
Configurare un utente di Microsoft Entra come amministratore per il database di Azure.
Connessione al database come utente di Microsoft Entra.
Configurare un'identità gestita assegnata dal sistema o assegnata dall'utente per un'app servizio app.
Concedere l'accesso al database all'identità gestita.
Connessione al database di Azure dal codice (.NET Framework 4.8, .NET 6, Node.js, Python, Java) usando un'identità gestita.
Connessione al database di Azure dall'ambiente di sviluppo usando l'utente di Microsoft Entra.
Creare un'app in servizio app basata su .NET, Node.js, Python o Java.
Creare un server di database con database SQL di Azure, Database di Azure per MySQL o Database di Azure per PostgreSQL.
Si dovrebbe avere familiarità con il modello di connettività standard (con nome utente e password) e potersi connettere correttamente dall'app servizio app al database preferito.
Preparare l'ambiente per l'interfaccia della riga di comando di Azure.
Se si preferisce eseguire i comandi di riferimento dell'interfaccia della riga di comando in locale, installare l'interfaccia della riga di comando di Azure. Per l'esecuzione in Windows o macOS, è consigliabile eseguire l'interfaccia della riga di comando di Azure in un contenitore Docker. Per altre informazioni, vedere Come eseguire l'interfaccia della riga di comando di Azure in un contenitore Docker.
Se si usa un'installazione locale, accedere all'interfaccia della riga di comando di Azure con il comando az login. Per completare il processo di autenticazione, seguire la procedura visualizzata nel terminale. Per altre opzioni di accesso, vedere Accedere tramite l'interfaccia della riga di comando di Azure.
Eseguire az version per trovare la versione e le librerie dipendenti installate. Per eseguire l'aggiornamento alla versione più recente, eseguire az upgrade.
1. Installare l'estensione senza password del servizio Connessione or
Installare l'estensione senza password del servizio Connessione or per l'interfaccia della riga di comando di Azure:
az extension add --name serviceconnector-passwordless --upgrade
2. Creare una connessione senza password
Creare quindi una connessione senza password con Service Connessione or.
Suggerimento
Il portale di Azure può essere utile per comporre i comandi seguenti. Nella portale di Azure passare alla risorsa del servizio app Azure, selezionare Service Connessione or (Servizio) dal menu a sinistra e selezionare Crea. Compilare il modulo con tutti i parametri obbligatori. Azure genera automaticamente il comando di creazione della connessione, che è possibile copiare da usare nell'interfaccia della riga di comando o eseguire in Azure Cloud Shell.
Per Database di Azure per MySQL - Server flessibile, è prima necessario configurare manualmente l'autenticazione di Microsoft Entra, che richiede un'identità gestita assegnata dall'utente separata e autorizzazioni specifiche di Microsoft Graph. Questo passaggio non può essere automatizzato.
Facoltativamente, eseguire il comando az webapp connection create mysql-flexible -h per ottenere i tipi di client supportati.
Scegliere un tipo di client ed eseguire il comando corrispondente. Il comando seguente dell'interfaccia della riga di comando di Azure usa un --client-type parametro .
Concedere l'autorizzazione alle tabelle create in modo preliminare
Successivamente, se sono state create tabelle e sequenze nel server flessibile PostgreSQL prima di usare Service Connessione or, è necessario connettersi come proprietario e concedere l'autorizzazione a <aad-username> creata da Service Connessione or. Il nome utente del stringa di connessione o della configurazione impostato da Service Connessione or dovrebbe essere simile aad_<connection name>a . Se si usa il portale di Azure, selezionare il pulsante di espansione accanto alla Service Type colonna e ottenere il valore. Se si usa l'interfaccia della riga di comando di Azure, archiviare configurations l'output del comando dell'interfaccia della riga di comando.
Eseguire quindi la query per concedere l'autorizzazione
az extension add --name rdbms-connect
az postgres flexible-server execute -n <postgres-name> -u <owner-username> -p "<owner-password>" -d <database-name> --querytext "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"<aad-username>\";GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO \"<aad username>\";"
<owner-username> e <owner-password> è il proprietario della tabella esistente che può concedere autorizzazioni ad altri utenti. <aad-username>è l'utente creato da Service Connessione or. Sostituirli con il valore effettivo.
Convalidare il risultato con il comando :
az postgres flexible-server execute -n <postgres-name> -u <owner-username> -p "<owner-password>" -d <database-name> --querytext "SELECT distinct(table_name) FROM information_schema.table_privileges WHERE grantee='<aad-username>' AND table_schema='public';" --output table
Questo comando service Connessione or completa le attività seguenti in background:
Abilitare l'identità gestita assegnata dal sistema o assegnare un'identità utente per l'app <server-name> ospitata da app Azure Servizio.
Impostare l'amministratore di Microsoft Entra sull'utente connesso corrente.
Aggiungere un utente del database per l'identità gestita assegnata dal sistema o l'identità gestita assegnata dall'utente. Concedere a questo utente tutti i privilegi del database <database-name> . Il nome utente è disponibile nella stringa di connessione nell'output del comando precedente.
Impostare le configurazioni denominate AZURE_MYSQL_CONNECTIONSTRING, AZURE_POSTGRESQL_CONNECTIONSTRINGo AZURE_SQL_CONNECTIONSTRING sulla risorsa di Azure in base al tipo di database.
Per servizio app, le configurazioni vengono impostate nel pannello App Impostazioni.
Se si verificano problemi durante la creazione di una connessione, vedere Risoluzione dei problemi per assistenza.
Ottenere il database SQL di Azure stringa di connessione dalla variabile di ambiente aggiunta da Service Connessione or.
using Microsoft.Data.SqlClient;
// AZURE_SQL_CONNECTIONSTRING should be one of the following:
// For system-assigned managed identity:"Server=tcp:<server-name>.database.windows.net;Database=<database-name>;Authentication=Active Directory Default;TrustServerCertificate=True"
// For user-assigned managed identity: "Server=tcp:<server-name>.database.windows.net;Database=<database-name>;Authentication=Active Directory Default;User Id=<client-id-of-user-assigned-identity>;TrustServerCertificate=True"
string connectionString =
Environment.GetEnvironmentVariable("AZURE_SQL_CONNECTIONSTRING")!;
using var connection = new SqlConnection(connectionString);
connection.Open();
Ottenere le configurazioni di connessione database SQL di Azure dalla variabile di ambiente aggiunta da Service Connessione or. Rimuovere il commento dalla parte del frammento di codice per il tipo di autenticazione che si vuole usare.
import os;
import pyodbc
server = os.getenv('AZURE_SQL_SERVER')
port = os.getenv('AZURE_SQL_PORT')
database = os.getenv('AZURE_SQL_DATABASE')
authentication = os.getenv('AZURE_SQL_AUTHENTICATION') # The value should be 'ActiveDirectoryMsi'
# Uncomment the following lines according to the authentication type.
# For system-assigned managed identity.
# connString = f'Driver={{ODBC Driver 18 for SQL Server}};Server={server},{port};Database={database};Authentication={authentication};Encrypt=yes;'
# For user-assigned managed identity.
# client_id = os.getenv('AZURE_SQL_USER')
# connString = f'Driver={{ODBC Driver 18 for SQL Server}};Server={server},{port};Database={database};UID={client_id};Authentication={authentication};Encrypt=yes;'
conn = pyodbc.connect(connString)
Ottenere le configurazioni di connessione database SQL di Azure dalle variabili di ambiente aggiunte da Service Connessione or. Rimuovere il commento dalla parte del frammento di codice per il tipo di autenticazione che si vuole usare.
Connessione ivity to the Database di Azure per MySQL nel codice segue il DefaultAzureCredential modello per tutti gli stack di linguaggi. DefaultAzureCredential è sufficientemente flessibile da adattarsi sia all'ambiente di sviluppo che all'ambiente di Azure. Quando viene eseguito in locale, può recuperare l'utente di Azure connesso dall'ambiente preferito (Visual Studio, Visual Studio Code, interfaccia della riga di comando di Azure o Azure PowerShell). Durante l'esecuzione in Azure, recupera l'identità gestita. È quindi possibile avere connettività al database sia in fase di sviluppo che in produzione. Il modello è il seguente:
Creare un'istanza di dalla DefaultAzureCredential libreria client di Identità di Azure. Se si usa un'identità assegnata dall'utente, specificare l'ID client dell'identità.
Ottenere un token di accesso per Database di Azure per MySQL: https://ossrdbms-aad.database.windows.net/.default.
Per .NET, ottenere un token di accesso per l'identità gestita usando una libreria client, ad esempio Azure.Identity. Usare quindi il token di accesso come password per connettersi al database. Quando si usa il codice seguente, assicurarsi di rimuovere il commento dalla parte del frammento di codice corrispondente al tipo di autenticazione che si vuole usare.
using Azure.Core;
using Azure.Identity;
using MySqlConnector;
// Uncomment the following lines according to the authentication type.
// For system-assigned managed identity.
// var credential = new DefaultAzureCredential();
// For user-assigned managed identity.
// var credential = new DefaultAzureCredential(
// new DefaultAzureCredentialOptions
// {
// ManagedIdentityClientId = Environment.GetEnvironmentVariable("AZURE_MYSQL_CLIENTID");
// });
var tokenRequestContext = new TokenRequestContext(
new[] { "https://ossrdbms-aad.database.windows.net/.default" });
AccessToken accessToken = await credential.GetTokenAsync(tokenRequestContext);
// Open a connection to the MySQL server using the access token.
string connectionString =
$"{Environment.GetEnvironmentVariable("AZURE_MYSQL_CONNECTIONSTRING")};Password={accessToken.Token}";
using var connection = new MySqlConnection(connectionString);
Console.WriteLine("Opening connection using access token...");
await connection.OpenAsync();
// do something
Aggiungere le dipendenze seguenti nel file pom.xml :
Eseguire l'autenticazione con un token di accesso dalla azure-identity libreria. Ottenere le informazioni di connessione dalla variabile di ambiente aggiunta da Service Connessione or. Quando si usa il codice seguente, assicurarsi di rimuovere il commento dalla parte del frammento di codice corrispondente al tipo di autenticazione che si vuole usare.
from azure.identity import ManagedIdentityCredential, ClientSecretCredential
import mysql.connector
import os
# Uncomment the following lines according to the authentication type.
# For system-assigned managed identity.
# cred = ManagedIdentityCredential()
# For user-assigned managed identity.
# managed_identity_client_id = os.getenv('AZURE_MYSQL_CLIENTID')
# cred = ManagedIdentityCredential(client_id=managed_identity_client_id)
# acquire token
accessToken = cred.get_token('https://ossrdbms-aad.database.windows.net/.default')
# open connect to Azure MySQL with the access token.
host = os.getenv('AZURE_MYSQL_HOST')
database = os.getenv('AZURE_MYSQL_NAME')
user = os.getenv('AZURE_MYSQL_USER')
password = accessToken.token
cnx = mysql.connector.connect(user=user,
password=password,
host=host,
database=database)
cnx.close()
Ottenere un token di accesso usando @azure/identity e le informazioni sul database MySQL di Azure dalle variabili di ambiente aggiunte da Service Connessione or. Quando si usa il codice seguente, assicurarsi di rimuovere il commento dalla parte del frammento di codice corrispondente al tipo di autenticazione che si vuole usare.
import { DefaultAzureCredential,ClientSecretCredential } from "@azure/identity";
const mysql = require('mysql2');
// Uncomment the following lines according to the authentication type.
// for system-assigned managed identity
// const credential = new DefaultAzureCredential();
// for user-assigned managed identity
// const clientId = process.env.AZURE_MYSQL_CLIENTID;
// const credential = new DefaultAzureCredential({
// managedIdentityClientId: clientId
// });
// acquire token
var accessToken = await credential.getToken('https://ossrdbms-aad.database.windows.net/.default');
const connection = mysql.createConnection({
host: process.env.AZURE_MYSQL_HOST,
user: process.env.AZURE_MYSQL_USER,
password: accessToken.token,
database: process.env.AZURE_MYSQL_DATABASE,
port: process.env.AZURE_MYSQL_PORT,
ssl: process.env.AZURE_MYSQL_SSL
});
connection.connect((err) => {
if (err) {
console.error('Error connecting to MySQL database: ' + err.stack);
return;
}
console.log('Connected to MySQL database');
});
Connessione ivity to the Database di Azure per PostgreSQL nel codice segue il DefaultAzureCredential modello per tutti gli stack di linguaggi. DefaultAzureCredential è sufficientemente flessibile da adattarsi sia all'ambiente di sviluppo che all'ambiente di Azure. Quando viene eseguito in locale, può recuperare l'utente di Azure connesso dall'ambiente preferito (Visual Studio, Visual Studio Code, interfaccia della riga di comando di Azure o Azure PowerShell). Durante l'esecuzione in Azure, recupera l'identità gestita. È quindi possibile avere connettività al database sia in fase di sviluppo che in produzione. Il modello è il seguente:
Creare un'istanza di dalla DefaultAzureCredential libreria client di Identità di Azure. Se si usa un'identità assegnata dall'utente, specificare l'ID client dell'identità.
Ottenere un token di accesso per Database di Azure per PostgreSQL: https://ossrdbms-aad.database.windows.net/.default.
Per .NET, ottenere un token di accesso per l'identità gestita usando una libreria client, ad esempio Azure.Identity. Usare quindi il token di accesso come password per connettersi al database. Quando si usa il codice seguente, assicurarsi di rimuovere il commento dalla parte del frammento di codice corrispondente al tipo di autenticazione che si vuole usare.
using Azure.Identity;
using Azure.Core;
using Npgsql;
// Uncomment the following lines according to the authentication type.
// For system-assigned identity.
// var sqlServerTokenProvider = new DefaultAzureCredential();
// For user-assigned identity.
// var sqlServerTokenProvider = new DefaultAzureCredential(
// new DefaultAzureCredentialOptions
// {
// ManagedIdentityClientId = Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CLIENTID");
// }
// );
// Acquire the access token.
AccessToken accessToken = await sqlServerTokenProvider.GetTokenAsync(
new TokenRequestContext(scopes: new string[]
{
"https://ossrdbms-aad.database.windows.net/.default"
}));
// Combine the token with the connection string from the environment variables provided by Service Connector.
string connectionString =
$"{Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CONNECTIONSTRING")};Password={accessToken.Token}";
// Establish the connection.
using (var connection = new NpgsqlConnection(connectionString))
{
Console.WriteLine("Opening connection using access token...");
connection.Open();
}
Aggiungere le dipendenze seguenti nel file pom.xml :
Eseguire l'autenticazione con un token di accesso dalla azure-identity libreria e usare il token come password. Ottenere le informazioni di connessione dalle variabili di ambiente aggiunte da Service Connessione or. Quando si usa il codice seguente, assicurarsi di rimuovere il commento dalla parte del frammento di codice corrispondente al tipo di autenticazione che si vuole usare.
from azure.identity import DefaultAzureCredential
import psycopg2
# Uncomment the following lines according to the authentication type.
# For system-assigned identity.
# cred = DefaultAzureCredential()
# For user-assigned identity.
# managed_identity_client_id = os.getenv('AZURE_POSTGRESQL_CLIENTID')
# cred = ManagedIdentityCredential(client_id=managed_identity_client_id)
# Acquire the access token
accessToken = cred.get_token('https://ossrdbms-aad.database.windows.net/.default')
# Combine the token with the connection string from the environment variables added by Service Connector to establish the connection.
conn_string = os.getenv('AZURE_POSTGRESQL_CONNECTIONSTRING')
conn = psycopg2.connect(conn_string + ' password=' + accessToken.token)
Nel codice ottenere il token di accesso tramite @azure/identity e le informazioni di connessione PostgreSQL dalle variabili di ambiente aggiunte dal servizio Connessione or del servizio. Combinarli per stabilire la connessione. Quando si usa il codice seguente, assicurarsi di rimuovere il commento dalla parte del frammento di codice corrispondente al tipo di autenticazione che si vuole usare.
import { DefaultAzureCredential, ClientSecretCredential } from "@azure/identity";
const { Client } = require('pg');
// Uncomment the following lines according to the authentication type.
// For system-assigned identity.
// const credential = new DefaultAzureCredential();
// For user-assigned identity.
// const clientId = process.env.AZURE_POSTGRESQL_CLIENTID;
// const credential = new DefaultAzureCredential({
// managedIdentityClientId: clientId
// });
// Acquire the access token.
var accessToken = await credential.getToken('https://ossrdbms-aad.database.windows.net/.default');
// Use the token and the connection information from the environment variables added by Service Connector to establish the connection.
(async () => {
const client = new Client({
host: process.env.AZURE_POSTGRESQL_HOST,
user: process.env.AZURE_POSTGRESQL_USER,
password: accesstoken.token,
database: process.env.AZURE_POSTGRESQL_DATABASE,
port: Number(process.env.AZURE_POSTGRESQL_PORT) ,
ssl: process.env.AZURE_POSTGRESQL_SSL
});
await client.connect();
await client.end();
})();
Questo codice di esempio usa DefaultAzureCredential per ottenere un token utilizzabile per il database di Azure dall'ID Microsoft Entra e quindi lo aggiunge alla connessione al database. Anche se è possibile personalizzare DefaultAzureCredential, è già versatile per impostazione predefinita. Ottiene un token dall'utente Microsoft Entra connesso o da un'identità gestita, a seconda che venga eseguito localmente nell'ambiente di sviluppo o in servizio app.
Senza ulteriori modifiche, il codice è pronto per l'esecuzione in Azure. Per eseguire il debug del codice in locale, tuttavia, l'ambiente di sviluppo richiede un utente connesso a Microsoft Entra. In questo passaggio si configura l'ambiente preferito accedendo con l'utente di Microsoft Entra.
Visual Studio per Windows è integrato con l'autenticazione Microsoft Entra. Per abilitare lo sviluppo e il debug in Visual Studio, aggiungere l'utente Microsoft Entra in Visual Studio selezionando Account file>Impostazioni dal menu e selezionare Accedi o Aggiungi.
Per impostare l'utente di Microsoft Entra per l'autenticazione del servizio di Azure, selezionare Strumenti>Opzioni dal menu e quindi selezionare Selezione dell'account di autenticazione del>servizio di Azure. Selezionare l'utente di Microsoft Entra aggiunto e selezionare OK.
Visual Studio per Mac non è integrato con l'autenticazione di Microsoft Entra. Tuttavia, la libreria client di Identità di Azure che verrà usata in un secondo momento può anche recuperare i token dall'interfaccia della riga di comando di Azure. Per abilitare lo sviluppo e il debug in Visual Studio, installare l'interfaccia della riga di comando di Azure nel computer locale.
Accedere all'interfaccia della riga di comando di Azure con il comando seguente usando l'utente di Microsoft Entra:
az login --allow-no-subscriptions
Visual Studio Code è integrato con l'autenticazione di Microsoft Entra tramite l'estensione Azure. Installare l'estensione Strumenti di Azure in Visual Studio Code.
Nella barra delle attività di Visual Studio Code selezionare il logo di Azure.
In Esplora servizio app selezionare Accedi ad Azure e seguire le istruzioni.
La libreria client di Identità di Azure che verrà usata in un secondo momento può usare i token dall'interfaccia della riga di comando di Azure. Per abilitare lo sviluppo basato sulla riga di comando, installare l'interfaccia della riga di comando di Azure nel computer locale.
Accedere ad Azure con il comando seguente usando l'utente di Microsoft Entra:
az login --allow-no-subscriptions
La libreria client di Identità di Azure che verrà usata in un secondo momento può usare i token di Azure PowerShell. Per abilitare lo sviluppo basato su riga di comando, installare Azure PowerShell nel computer locale.
Accedere all'interfaccia della riga di comando di Azure con il cmdlet seguente usando l'utente di Microsoft Entra:
A questo punto è possibile sviluppare ed eseguire il debug dell'app con il database SQL come back-end, usando l'autenticazione di Microsoft Entra.
5. Testare e pubblicare
Eseguire il codice nell'ambiente di sviluppo. Il codice usa l'utente connesso di Microsoft Entra nell'ambiente per connettersi al database back-end. L'utente può accedere al database perché è configurato come amministratore di Microsoft Entra per il database.
Pubblicare il codice in Azure usando il metodo di pubblicazione preferito. In servizio app il codice usa l'identità gestita dell'app per connettersi al database back-end.
L'ID Microsoft Entra e le identità gestite non sono supportate per SQL Server locale.
Viene visualizzato l'errore Login failed for user '<token-identified principal>'.
L'identità gestita per cui si sta tentando di richiedere un token non è autorizzata ad accedere al database di Azure.
Sono state apportate modifiche all'autenticazione servizio app o alla registrazione dell'app associata. Perché si ottiene ancora il vecchio token?
I servizi back-end delle identità gestite mantengono anche una cache dei token che aggiorna il token per una risorsa di destinazione solo quando scade. Se si modifica la configurazione dopo aver tentato di ottenere un token con l'app, non si ottiene effettivamente un nuovo token con le autorizzazioni aggiornate fino alla scadenza del token memorizzato nella cache. Il modo migliore per risolvere questo problema consiste nel testare le modifiche con una nuova finestra InPrivate (Edge)/privata (Safari)/Incognito (Chrome). In questo modo, si è sicuri di iniziare da una nuova sessione autenticata.
Ricerca per categorie aggiungere l'identità gestita a un gruppo Microsoft Entra?
Se si vuole, è possibile aggiungere l'identità a un gruppo Microsoft Entra, quindi concedere l'accesso al gruppo Microsoft Entra anziché all'identità. Ad esempio, i comandi seguenti aggiungono l'identità gestita del passaggio precedente a un nuovo gruppo denominato myAzureSQLDBAccessGroup:
groupid=$(az ad group create --display-name myAzureSQLDBAccessGroup --mail-nickname myAzureSQLDBAccessGroup --query objectId --output tsv)
msiobjectid=$(az webapp identity show --resource-group <group-name> --name <app-name> --query principalId --output tsv)
az ad group member add --group $groupid --member-id $msiobjectid
az ad group member list -g $groupid
Per concedere le autorizzazioni di database per un gruppo Microsoft Entra, vedere la documentazione relativa al tipo di database corrispondente.
Viene visualizzato l'errore SSL connection is required. Please specify SSL options and retry.
Connessione al database di Azure richiede impostazioni aggiuntive ed esula dall'ambito di questa esercitazione. Per altre informazioni, vedere uno dei collegamenti seguenti: