Connettersi con l'identità gestita al Database di Azure per MySQL

SI APPLICA A: Database di Azure per MySQL - Server singolo

Importante

Database di Azure per MySQL server singolo si trova nel percorso di ritiro. È consigliabile eseguire l'aggiornamento a Database di Azure per MySQL server flessibile. Per altre informazioni sulla migrazione a Database di Azure per MySQL server flessibile, vedere Che cosa accade a Database di Azure per MySQL server singolo?

Questo articolo illustra come usare un'identità assegnata dall'utente per una macchina virtuale di Azure per accedere a un server di Database di Azure per MySQL. Le identità del servizio gestito vengono gestite automaticamente da Azure e consentono di eseguire l'autenticazione ai servizi che supportano l'autenticazione di Microsoft Entra, senza dover inserire le credenziali nel codice.

Scopri come:

  • Concedere l'accesso della macchina virtuale a un server di Database di Azure per MySQL
  • Creare un utente nel database che rappresenta l'identità assegnata dall'utente della macchina virtuale
  • Ottenere un token di accesso tramite l'identità della macchina virtuale e usarlo per eseguire query su un server di Database di Azure per MySQL
  • Implementare il recupero dei token in un'applicazione C# di esempio

Importante

Connessione con identità gestita è disponibile solo per MySQL 5.7 e versioni successive.

Prerequisiti

  • Se non si ha familiarità con la funzionalità delle identità gestite per le risorse di Azure, vedere questa panoramica. Se non si ha un account Azure, registrarsi per ottenere un account gratuito prima di continuare.
  • Per eseguire le attività richieste di creazione delle risorse e gestione dei ruoli, l'account deve avere le autorizzazioni "Proprietario" nell'ambito appropriato (sottoscrizione o gruppo di risorse). Se è necessaria assistenza per l'assegnazione di ruolo, vedere Assegnare i ruoli di Azure per gestire l'accesso alle risorse della sottoscrizione di Azure.
  • È necessaria una macchina virtuale di Azure, ad esempio che esegue Ubuntu Linux, da usare per l'accesso al database tramite l'identità gestita
  • È necessario un server di database Database di Azure per MySQL con l'autenticazione di Microsoft Entra configurata
  • Per seguire l'esempio in C#, completare prima di tutto la procedura per connettersi tramite C#

Creazione di un'identità gestita assegnata dall'utente per la VM

Creare un'identità nella sottoscrizione usando il comando az identity create. È possibile usare lo stesso gruppo di risorse in cui viene eseguita la macchina virtuale o un altro.

az identity create --resource-group myResourceGroup --name myManagedIdentity

Per configurare l'identità nei passaggi seguenti, usare il comando az identity show per archiviare l'ID risorsa e l'ID client dell'entità in variabili.

# Get resource ID of the user-assigned identity

RESOURCE_ID=$(az identity show --resource-group myResourceGroup --name myManagedIdentity --query id --output tsv)

# Get client ID of the user-assigned identity


CLIENT_ID=$(az identity show --resource-group myResourceGroup --name myManagedIdentity --query clientId --output tsv)

È ora possibile assegnare l'identità assegnata dall'utente alla macchina virtuale con il comando az vm identity assign:

az vm identity assign --resource-group myResourceGroup --name myVM --identities $RESOURCE_ID

Per completare la configurazione, visualizzare il valore dell'ID cliente, che sarà necessario nei passaggi successivi:

echo $CLIENT_ID

Creazione di un utente di MySQL per l'identità gestita

Connettersi ora come utente amministratore di Microsoft Entra al database MySQL ed eseguire le istruzioni SQL seguenti:

SET aad_auth_validate_oids_in_tenant = OFF;
CREATE AADUSER 'myuser' IDENTIFIED BY 'CLIENT_ID';

L'identità gestita ha ora accesso quando esegue l'autenticazione con il nome utente myuser (sostituire con un nome a scelta).

Recupero del token di accesso dal servizio metadati dell'istanza di Azure

L'applicazione può ora recuperare un token di accesso dal servizio metadati dell'istanza di Azure e usarlo per l'autenticazione con il database.

Il recupero di questo token viene eseguito effettuando una richiesta HTTP a http://169.254.169.254/metadata/identity/oauth2/token e passando i parametri seguenti:

  • api-version = 2018-02-01
  • resource = https://ossrdbms-aad.database.windows.net
  • client_id = CLIENT_ID (recuperato in precedenza)

Si otterrà un risultato JSON che contiene un campo access_token: questo valore di testo lungo è il token di accesso dell'identità gestita, da usare come password per connettersi al database.

A scopo di test, è possibile eseguire i comandi seguenti nella shell. Si noti che è necessario che siano installati curl, jq e il client mysql.

# Retrieve the access token


ACCESS_TOKEN=$(curl -s 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fossrdbms-aad.database.windows.net&client_id=CLIENT_ID' -H Metadata:true | jq -r .access_token)

# Connect to the database


mysql -h SERVER --user USER@SERVER --enable-cleartext-plugin --password=$accessToken

A questo punto si è connessi al database configurato in precedenza.

Connessione tramite identità gestita in C#

Questa sezione illustra come ottenere un token di accesso usando l'identità gestita assegnata dall'utente della macchina virtuale e usarlo per chiamare Database di Azure per MySQL. Database di Azure per MySQL supporta in modo nativo l'autenticazione di Microsoft Entra, in modo che possa accettare direttamente i token di accesso ottenuti usando le identità gestite per le risorse di Azure. Quando si crea una connessione a MySQL, si passa il token di accesso nel campo della password.

Di seguito è riportato un esempio di codice .NET per l'apertura di una connessione a MySQL tramite un token di accesso. Questo codice deve essere eseguito nella macchina virtuale per poter accedere all'endpoint dell'identità gestita assegnata dall'utente della macchina virtuale. Per usare il metodo del token di accesso, è necessario .NET Framework 4.6 o versione successiva oppure .NET Core 2.2 o versione successiva. Sostituire i valori di HOST, USER, DATABASE e CLIENT_ID.

using System;
using System.Net;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;

namespace Driver
{
    class Script
    {
        // Obtain connection string information from the portal
        //
        private static string Host = "HOST";
        private static string User = "USER";
        private static string Database = "DATABASE";
        private static string ClientId = "CLIENT_ID";

        static async Task Main(string[] args)
        {
            //
            // Get an access token for MySQL.
            //
            Console.Out.WriteLine("Getting access token from Azure Instance Metadata service...");

            // Azure AD resource ID for Azure Database for MySQL is https://ossrdbms-aad.database.windows.net/
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fossrdbms-aad.database.windows.net&client_id=" + ClientId);
            request.Headers["Metadata"] = "true";
            request.Method = "GET";
            string accessToken = null;

            try
            {
                // Call managed identities for Azure resources endpoint.
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                // Pipe response Stream to a StreamReader and extract access token.
                StreamReader streamResponse = new StreamReader(response.GetResponseStream());
                string stringResponse = streamResponse.ReadToEnd();
                var list = JsonSerializer.Deserialize<Dictionary<string, string>>(stringResponse);
                accessToken = list["access_token"];
            }
            catch (Exception e)
            {
                Console.Out.WriteLine("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : "Acquire token failed");
                System.Environment.Exit(1);
            }

            //
            // Open a connection to the MySQL server using the access token.
            //
            var builder = new MySqlConnectionStringBuilder
            {
                Server = Host,
                Database = Database,
                UserID = User,
                Password = accessToken,
                SslMode = MySqlSslMode.Required,
            };

            using (var conn = new MySqlConnection(builder.ConnectionString))
            {
                Console.Out.WriteLine("Opening connection using access token...");
                await conn.OpenAsync();

                using (var command = conn.CreateCommand())
                {
                    command.CommandText = "SELECT VERSION()";

                    using (var reader = await command.ExecuteReaderAsync())
                    {
                        while (await reader.ReadAsync())
                        {
                            Console.WriteLine("\nConnected!\n\nMySQL version: {0}", reader.GetString(0));
                        }
                    }
                }
            }
        }
    }
}

Quando viene eseguito, questo comando restituirà un output simile al seguente:

Getting access token from Azure Instance Metadata service...
Opening connection using access token...

Connected!

MySQL version: 5.7.27

Passaggi successivi