Självstudie: Ansluta till Azure-databaser från App Service utan hemligheter med hjälp av en hanterad identitet
Artikel
Med App Service får du en automatiskt uppdaterad webbvärdtjänst i Azure med hög skalbarhet. Den tillhandahåller också en hanterad identitet för din app, vilket är en nyckelfärdig lösning för att skydda åtkomsten till Azure-databaser, inklusive:
Med hanterade identiteter i App Service blir dina appar säkrare eftersom du inte har några hemligheter i dina appar. Du har till exempel inga inloggningsuppgifter i anslutningssträngarna. Den här självstudien visar hur du ansluter till ovan nämnda databaser från App Service med hjälp av hanterade identiteter.
Vad du kommer att lära dig:
Konfigurera en Microsoft Entra-användare som administratör för din Azure-databas.
Anslut till databasen som Microsoft Entra-användare.
Konfigurera en systemtilldelad eller användartilldelad hanterad identitet för en App Service-app.
Bevilja databasåtkomst till den hanterade identiteten.
Anslut till Azure-databasen från din kod (.NET Framework 4.8, .NET 6, Node.js, Python, Java) med hjälp av en hanterad identitet.
Anslut till Azure-databasen från utvecklingsmiljön med hjälp av Microsoft Entra-användaren.
Om du använder en lokal installation loggar du in på Azure CLI med hjälp av kommandot az login. Slutför autentiseringsprocessen genom att följa stegen som visas i terminalen. Andra inloggningsalternativ finns i Logga in med Azure CLI.
När du uppmanas att installera Azure CLI-tillägget vid första användningen. Mer information om tillägg finns i Använda tillägg med Azure CLI.
Kör az version om du vill hitta versionen och de beroende bibliotek som är installerade. Om du vill uppgradera till den senaste versionen kör du az upgrade.
1. Installera det lösenordslösa tillägget för Service Connector
Installera det senaste lösenordslösa tillägget för Service Connector för Azure CLI:
az extension add --name serviceconnector-passwordless --upgrade
Kommentar
Kontrollera att tillägget "serviceconnector-passwordless" är "2.0.2" eller senare genom att köra az version. Du kan behöva uppgradera Azure CLI först för att uppgradera tilläggsversionen.
2. Skapa en lösenordslös anslutning
Skapa sedan en lösenordslös anslutning med Service Connector.
Dricks
Azure Portal kan hjälpa dig att skriva kommandona nedan. I Azure Portal går du till din Azure App Service-resurs, väljer Service Connector på den vänstra menyn och väljer Skapa. Fyll i formuläret med alla obligatoriska parametrar. Azure genererar automatiskt kommandot för att skapa anslutningar, som du kan kopiera för att använda i CLI eller köra i Azure Cloud Shell.
För Azure Database for MySQL – flexibel server måste du först konfigurera Microsoft Entra-autentisering manuellt, vilket kräver en separat användartilldelad hanterad identitet och specifika Microsoft Graph-behörigheter. Det här steget kan inte automatiseras.
Om du sedan har skapat tabeller och sekvenser i En flexibel PostgreSQL-server innan du använder Service Connector, måste du ansluta som ägare och bevilja behörighet till skapad <aad-username> av Service Connector. Användarnamnet från anslutningssträng eller konfigurationsuppsättningen i Service Connector bör se ut som aad_<connection name>. Om du använder Azure Portal väljer du knappen expandera bredvid Service Type kolumnen och hämtar värdet. Om du använder Azure CLI kontrollerar configurations du CLI-kommandoutdata.
Kör sedan frågan för att bevilja behörighet
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>\";"
Och <owner-username><owner-password> är ägare till den befintliga tabellen som kan bevilja behörigheter till andra. <aad-username> är användaren som skapats av Service Connector. Ersätt dem med det faktiska värdet.
Verifiera resultatet med kommandot :
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
Det här service connector-kommandot slutför följande uppgifter i bakgrunden:
Aktivera systemtilldelad hanterad identitet eller tilldela en användaridentitet för appen <server-name> som hanteras av Azure App Service.
Ange Microsoft Entra-administratören till den aktuella inloggade användaren.
Lägg till en databasanvändare för den systemtilldelade hanterade identiteten eller den användartilldelade hanterade identiteten. Bevilja alla behörigheter för databasen <database-name> till den här användaren. Användarnamnet finns i anslutningssträng i föregående kommandoutdata.
Ange konfigurationer med namnet AZURE_MYSQL_CONNECTIONSTRING, AZURE_POSTGRESQL_CONNECTIONSTRINGeller AZURE_SQL_CONNECTIONSTRING till Azure-resursen baserat på databastypen.
För App Service anges konfigurationerna på bladet Appinställningar .
Om du stöter på problem när du skapar en anslutning kan du läsa Felsökning för hjälp.
Hämta Azure SQL Database-anslutningssträng från miljövariabeln som lagts till av Service Connector.
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();
Hämta Azure SQL Database-anslutningskonfigurationerna från miljövariabeln som lagts till av Service Connector. Ta bort kommentaren till den del av kodfragmentet för den autentiseringstyp som du vill använda.
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)
Hämta Azure SQL Database-anslutningskonfigurationerna från miljövariablerna som lagts till av Service Connector. Ta bort kommentaren till den del av kodfragmentet för den autentiseringstyp som du vill använda.
Anslutningen till Azure Database for MySQL i koden följer DefaultAzureCredential mönstret för alla språkstackar. DefaultAzureCredential är tillräckligt flexibel för att anpassas till både utvecklingsmiljön och Azure-miljön. När den körs lokalt kan den hämta den inloggade Azure-användaren från valfri miljö (Visual Studio, Visual Studio Code, Azure CLI eller Azure PowerShell). När den körs i Azure hämtas den hanterade identiteten. Därför är det möjligt att ha anslutning till databasen både vid utvecklingstillfället och i produktion. Mönstret är följande:
Instansiera en DefaultAzureCredential från Azure Identity-klientbiblioteket. Om du använder en användartilldelad identitet anger du identitetens klient-ID.
Hämta en åtkomsttoken för Azure Database for MySQL: https://ossrdbms-aad.database.windows.net/.default.
För .NET hämtar du en åtkomsttoken för den hanterade identiteten med hjälp av ett klientbibliotek som Azure.Identity. Använd sedan åtkomsttoken som ett lösenord för att ansluta till databasen. När du använder koden nedan ser du till att du avkommenterar den del av kodfragmentet som motsvarar den autentiseringstyp som du vill använda.
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
Autentisera azure-identity med en åtkomsttoken från biblioteket. Hämta anslutningsinformationen från miljövariabeln som lagts till av Service Connector. När du använder koden nedan ser du till att du avkommenterar den del av kodfragmentet som motsvarar den autentiseringstyp som du vill använda.
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()
Hämta en åtkomsttoken med hjälp av @azure/identity och Azure MySQL-databasinformationen från miljövariablerna som lagts till av Service Connector. När du använder koden nedan ser du till att du avkommenterar den del av kodfragmentet som motsvarar den autentiseringstyp som du vill använda.
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');
});
Anslutningen till Azure Database for PostgreSQL i koden följer DefaultAzureCredential mönstret för alla språkstackar. DefaultAzureCredential är tillräckligt flexibel för att anpassas till både utvecklingsmiljön och Azure-miljön. När den körs lokalt kan den hämta den inloggade Azure-användaren från valfri miljö (Visual Studio, Visual Studio Code, Azure CLI eller Azure PowerShell). När den körs i Azure hämtas den hanterade identiteten. Därför är det möjligt att ha anslutning till databasen både vid utvecklingstillfället och i produktion. Mönstret är följande:
Instansiera en DefaultAzureCredential från Azure Identity-klientbiblioteket. Om du använder en användartilldelad identitet anger du identitetens klient-ID.
Hämta en åtkomsttoken för Azure Database for PostgreSQL: https://ossrdbms-aad.database.windows.net/.default.
För .NET hämtar du en åtkomsttoken för den hanterade identiteten med hjälp av ett klientbibliotek som Azure.Identity. Använd sedan åtkomsttoken som ett lösenord för att ansluta till databasen. När du använder koden nedan ser du till att du avkommenterar den del av kodfragmentet som motsvarar den autentiseringstyp som du vill använda.
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();
}
Autentisera azure-identity med en åtkomsttoken från biblioteket och använd token som lösenord. Hämta anslutningsinformationen från miljövariablerna som lagts till av Service Connector. När du använder koden nedan ser du till att du avkommenterar den del av kodfragmentet som motsvarar den autentiseringstyp som du vill använda.
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)
I kod hämtar du åtkomsttoken via @azure/identity och PostgreSQL-anslutningsinformation från miljövariabler som lagts till av Service Connector-tjänsten. Kombinera dem för att upprätta anslutningen. När du använder koden nedan ser du till att du avkommenterar den del av kodfragmentet som motsvarar den autentiseringstyp som du vill använda.
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();
})();
Den här exempelkoden använder DefaultAzureCredential för att hämta en användbar token för din Azure-databas från Microsoft Entra-ID och lägger sedan till den i databasanslutningen. Även om du kan anpassa DefaultAzureCredentialär det redan mångsidigt som standard. Den hämtar en token från den inloggade Microsoft Entra-användaren eller från en hanterad identitet, beroende på om du kör den lokalt i utvecklingsmiljön eller i App Service.
Utan ytterligare ändringar är koden redo att köras i Azure. För att felsöka koden lokalt behöver dock utvecklingsmiljön en inloggad Microsoft Entra-användare. I det här steget konfigurerar du valfri miljö genom att logga in med din Microsoft Entra-användare.
Visual Studio för Windows är integrerat med Microsoft Entra-autentisering. Om du vill aktivera utveckling och felsökning i Visual Studio lägger du till din Microsoft Entra-användare i Visual Studio genom att välja Inställningar för filkonto>på menyn och välja Logga in eller Lägg till.
Om du vill ange Microsoft Entra-användaren för Azure-tjänstautentisering väljer du Verktygsalternativ> på menyn och väljer sedan Kontoval för Azure-tjänstautentisering.> Välj den Microsoft Entra-användare som du lade till och välj OK.
Visual Studio för Mac är inte integrerat med Microsoft Entra-autentisering. Det Azure Identity-klientbibliotek som du ska använda senare kan dock också hämta token från Azure CLI. Om du vill aktivera utveckling och felsökning i Visual Studio installerar du Azure CLI på den lokala datorn.
Logga in på Azure CLI med följande kommando med din Microsoft Entra-användare:
az login --allow-no-subscriptions
Visual Studio Code är integrerat med Microsoft Entra-autentisering via Azure-tillägget. Installera Azure Tools-tillägget i Visual Studio Code.
I Visual Studio Code går du till aktivitetsfältet och väljer Azure-logotypen.
I App Service-utforskaren väljer du Logga in på Azure... och följer anvisningarna.
Azure Identity-klientbiblioteket som du ska använda senare kan använda token från Azure CLI. Om du vill aktivera kommandoradsbaserad utveckling installerar du Azure CLI på den lokala datorn.
Logga in på Azure med följande kommando med din Microsoft Entra-användare:
az login --allow-no-subscriptions
Azure Identity-klientbiblioteket som du ska använda senare kan använda token från Azure PowerShell. Om du vill aktivera kommandoradsbaserad utveckling installerar du Azure PowerShell på den lokala datorn.
Logga in på Azure CLI med följande cmdlet med din Microsoft Entra-användare:
Nu är du redo att utveckla och felsöka din app med SQL Database som serverdel med hjälp av Microsoft Entra-autentisering.
5. Testa och publicera
Kör koden i utvecklingsmiljön. Koden använder den inloggade Microsoft Entra-användaren i din miljö för att ansluta till serverdelsdatabasen. Användaren kan komma åt databasen eftersom den är konfigurerad som Microsoft Entra-administratör för databasen.
Publicera din kod till Azure med den föredragna publiceringsmetoden. I App Service använder koden appens hanterade identitet för att ansluta till serverdelsdatabasen.
Jag får felet Login failed for user '<token-identified principal>'.
Den hanterade identitet som du försöker begära en token för har inte behörighet att komma åt Azure-databasen.
Jag har gjort ändringar i App Service-autentiseringen eller den associerade appregistreringen. Varför får jag fortfarande den gamla token?
Serverdelstjänsterna för hanterade identiteter har också en tokencache som uppdaterar token för en målresurs endast när den upphör att gälla. Om du ändrar konfigurationen efter att ha försökt hämta en token med din app får du inte någon ny token med de uppdaterade behörigheterna förrän den cachelagrade token upphör att gälla. Det bästa sättet att kringgå detta är att testa dina ändringar med ett nytt InPrivate-fönster (Edge)/privat (Safari)/Incognito (Chrome). På så sätt kommer du säkert att börja från en ny autentiserad session.
Hur gör jag för att lägga till den hanterade identiteten i en Microsoft Entra-grupp?
Om du vill kan du lägga till identiteten i en Microsoft Entra-grupp och sedan bevilja åtkomst till Microsoft Entra-gruppen i stället för identiteten. Följande kommandon lägger till den hanterade identiteten från föregående steg till en ny grupp med namnet 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
Information om hur du beviljar databasbehörigheter för en Microsoft Entra-grupp finns i dokumentationen för respektive databastyp.
Jag får felet SSL connection is required. Please specify SSL options and retry.
Anslutning till Azure-databasen kräver ytterligare inställningar och ligger utanför omfånget för den här självstudien. Mer information finns i någon av följande länkar:
Jag har skapat min app med mallen Web App + Database och nu kan jag inte konfigurera en hanterad identitetsanslutning med kommandona för Service Connector.
Service Connector behöver nätverksåtkomst till databasen för att bevilja åtkomst för appidentiteten. När du skapar en säker app- och databasarkitektur i Azure Portal med mallen Webbapp + Databas låser arkitekturen nätverksåtkomsten till databasen och tillåter endast anslutningar inifrån det virtuella nätverket. Det gäller även för Azure Cloud Shell. Du kan dock distribuera Cloud Shell i det virtuella nätverket och sedan köra kommandot Service Connector i cloud shell.
Nästa steg
Vad du lärt dig:
Konfigurera en Microsoft Entra-användare som administratör för din Azure-databas.
Anslut till databasen som Microsoft Entra-användare.
Konfigurera en systemtilldelad eller användartilldelad hanterad identitet för en App Service-app.
Bevilja databasåtkomst till den hanterade identiteten.
Anslut till Azure-databasen från din kod (.NET Framework 4.8, .NET 6, Node.js, Python, Java) med hjälp av en hanterad identitet.
Anslut till Azure-databasen från utvecklingsmiljön med hjälp av Microsoft Entra-användaren.