Configurare connessioni senza password tra più app e servizi di Azure
Articolo
Le applicazioni richiedono spesso connessioni sicure tra più servizi di Azure contemporaneamente. Ad esempio, un'istanza del servizio app Azure aziendale potrebbe connettersi a diversi account di archiviazione, un'istanza del database SQL di Azure, un bus di servizio e altro ancora.
Le identità gestite sono l'opzione di autenticazione consigliata per connessioni sicure senza password tra le risorse di Azure. Gli sviluppatori non devono tenere traccia e gestire manualmente molti segreti diversi per le identità gestite, poiché la maggior parte di queste attività viene gestita internamente da Azure. Questa esercitazione illustra come gestire le connessioni tra più servizi usando identità gestite e la libreria client di Identità di Azure.
Confrontare i tipi di identità gestite
Azure offre i tipi di identità gestite seguenti:
Le identità gestite assegnate dal sistema sono direttamente collegate a una singola risorsa di Azure. Quando si abilita un'identità gestita assegnata dal sistema in un servizio, Azure creerà un'identità collegata e gestirà le attività amministrative per tale identità internamente. Quando la risorsa di Azure viene eliminata, viene eliminata anche l'identità.
Le identità gestite assegnate dall'utente sono identità indipendenti create da un amministratore e possono essere associate a una o più risorse di Azure. Il ciclo di vita dell'identità è indipendente da tali risorse.
Altre informazioni sulle procedure consigliate e su quando usare le identità assegnate dal sistema rispetto alle identità assegnate dall'utente nelle raccomandazioni sulle procedure consigliate per le identità.
Esplorare DefaultAzureCredential
Le identità gestite vengono in genere implementate nel codice dell'applicazione tramite una classe chiamata DefaultAzureCredential dalla Azure.Identity libreria client. DefaultAzureCredential supporta più metodi di autenticazione e determina automaticamente quali devono essere usati in fase di esecuzione. Per altre informazioni su questo approccio, vedere la panoramica di DefaultAzureCredential.
Connessione un'app ospitata in Azure a più servizi di Azure
È stato eseguito il compito di connettere un'app esistente a più servizi e database di Azure usando connessioni senza password. L'applicazione è un'API Web di ASP.NET Core ospitata nel servizio app Azure, anche se i passaggi seguenti si applicano anche ad altri ambienti di hosting di Azure, ad esempio Azure Spring Apps, Macchine virtuali, App contenitore e servizio Azure Kubernetes.
Questa esercitazione si applica alle architetture seguenti, anche se può essere adattata a molti altri scenari e tramite modifiche minime alla configurazione.
La procedura seguente illustra come configurare un'app per l'uso di un'identità gestita assegnata dal sistema e dell'account di sviluppo locale per connettersi a più servizi di Azure.
Creare un'identità gestita assegnata dal sistema
Nella portale di Azure passare all'applicazione ospitata che si vuole connettere ad altri servizi.
Nella pagina di panoramica del servizio selezionare Identità.
Impostare Statosu Sì per abilitare un'identità gestita assegnata dal sistema per il servizio.
Assegnare ruoli all'identità gestita per ogni servizio connesso
Passare alla pagina di panoramica dell'account di archiviazione a cui si vuole concedere l'accesso all'identità.
Selezionare Controllo di accesso (IAM) nel riquadro di spostamento dell'account di archiviazione.
Scegliere + Aggiungi e quindi Aggiungi assegnazione di ruolo.
Nella casella di ricerca Ruolo cercare Archiviazione Collaboratore dati BLOB, che concede le autorizzazioni per eseguire operazioni di lettura e scrittura sui dati BLOB. È possibile assegnare qualsiasi ruolo appropriato per il caso d'uso. Selezionare l'Archiviazione Collaboratore dati BLOB nell'elenco e scegliere Avanti.
Nella schermata Aggiungi assegnazione di ruolo selezionare Identità gestita per l'opzione Assegna accesso a. Scegliere quindi +Seleziona membri.
Nel riquadro a comparsa cercare l'identità gestita creata immettendo il nome del servizio app. Selezionare l'identità assegnata dal sistema e quindi scegliere Seleziona per chiudere il menu a comparsa.
Selezionare Avanti un paio di volte fino a quando non è possibile selezionare Rivedi e assegna per completare l'assegnazione di ruolo.
Ripetere questo processo per gli altri servizi a cui ci si vuole connettere.
Considerazioni sullo sviluppo locale
È anche possibile abilitare l'accesso alle risorse di Azure per lo sviluppo locale assegnando ruoli a un account utente nello stesso modo in cui sono stati assegnati ruoli all'identità gestita.
Dopo aver assegnato il ruolo Collaboratore dati BLOB Archiviazione all'identità gestita, in Assegna accesso a questa volta selezionare Utente, gruppo o entità servizio. Scegliere + Seleziona membri per aprire di nuovo il menu a comparsa.
Cercare l'account user@domain o il gruppo di sicurezza Microsoft Entra a cui si vuole concedere l'accesso tramite indirizzo di posta elettronica o nome e quindi selezionarlo. Questo deve essere lo stesso account usato per accedere agli strumenti di sviluppo locali, ad esempio Visual Studio o l'interfaccia della riga di comando di Azure.
Nota
È anche possibile assegnare questi ruoli a un gruppo di sicurezza Di Microsoft Entra se si lavora a un team con più sviluppatori. È quindi possibile inserire qualsiasi sviluppatore all'interno di tale gruppo che deve accedere per sviluppare l'app in locale.
All'interno del progetto aggiungere un riferimento al Azure.Identity pacchetto NuGet. Questa libreria contiene tutte le entità necessarie per implementare DefaultAzureCredential. È anche possibile aggiungere qualsiasi altra libreria di Azure pertinente per l'app. Per questo esempio, i Azure.Storage.Blobs pacchetti e Azure.KeyVault.Keys vengono aggiunti per connettersi all'Archiviazione BLOB e all'insieme di credenziali delle chiavi.
Nella parte superiore del Program.cs file aggiungere le istruzioni using seguenti:
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Security.KeyVault.Keys;
Program.cs Nel file del codice del progetto creare istanze dei servizi necessari a cui si connetterà l'app. Gli esempi seguenti si connettono al Archiviazione BLOB e al bus di servizio usando le classi SDK corrispondenti.
var blobServiceClient = new BlobServiceClient(
new Uri("https://<your-storage-account>.blob.core.windows.net"),
new DefaultAzureCredential(credOptions));
var serviceBusClient = new ServiceBusClient("<your-namespace>", new DefaultAzureCredential());
var sender = serviceBusClient.CreateSender("producttracking");
All'interno del progetto aggiungere la azure-identity dipendenza al file pom.xml . Questa libreria contiene tutte le entità necessarie per implementare DefaultAzureCredential. È anche possibile aggiungere altre dipendenze di Azure rilevanti per l'app. Per questo esempio, le azure-storage-blob dipendenze e azure-messaging-servicebus vengono aggiunte per connettersi all'Archiviazione BLOB e all'insieme di credenziali delle chiavi.
Nel codice del progetto creare istanze dei servizi necessari a cui si connetterà l'app. Gli esempi seguenti si connettono al Archiviazione BLOB e al bus di servizio usando le classi SDK corrispondenti.
class Demo {
public static void main(String[] args) {
DefaultAzureCredential defaultAzureCredential = new DefaultAzureCredentialBuilder().build();
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<your-storage-account>.blob.core.windows.net")
.credential(defaultAzureCredential)
.buildClient();
ServiceBusClientBuilder clientBuilder = new ServiceBusClientBuilder().credential(defaultAzureCredential);
ServiceBusSenderClient serviceBusSenderClient = clientBuilder.sender()
.queueName("producttracking")
.buildClient();
}
}
All'interno del progetto, è sufficiente aggiungere dipendenze del servizio usate. Per questo esempio, le spring-cloud-azure-starter-storage-blob dipendenze e spring-cloud-azure-starter-servicebus vengono aggiunte per connettersi all'Archiviazione BLOB e all'insieme di credenziali delle chiavi.
Nel codice del progetto creare istanze dei servizi necessari a cui si connetterà l'app. Gli esempi seguenti si connettono al Archiviazione BLOB e al bus di servizio usando le classi SDK corrispondenti.
@Service
public class ExampleService {
@Autowired
private BlobServiceClient blobServiceClient;
@Autowired
private ServiceBusSenderClient serviceBusSenderClient;
}
All'interno del progetto usare npm per aggiungere un riferimento al @azure/identity pacchetto. Questa libreria contiene tutte le entità necessarie per implementare DefaultAzureCredential. Installare tutte le altre librerie di Azure SDK rilevanti per l'app.
Nella parte superiore del index.js file aggiungere le istruzioni seguenti import per importare le classi client necessarie per i servizi a cui si connetterà l'app:
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";
import { KeyClient } from "@azure/keyvault-keys";
All'interno del index.js file creare oggetti client per i servizi di Azure a cui si connetterà l'app. Gli esempi seguenti si connettono all'Archiviazione BLOB e all'insieme di credenziali delle chiavi usando le classi SDK corrispondenti.
// Azure resource names
const storageAccount = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const keyVaultName = process.env.AZURE_KEYVAULT_NAME;
// Create client for Blob Storage using managed identity
const blobServiceClient = new BlobServiceClient(
`https://${storageAccount}.blob.core.windows.net`,
new DefaultAzureCredential()
);
// Create client for Key Vault using managed identity
const keyClient = new KeyClient(`https://${keyVaultName}.vault.azure.net`, new DefaultAzureCredential());
// Create a new key in Key Vault
const result = await keyClient.createKey(keyVaultName, "RSA");
Quando il codice dell'applicazione viene eseguito in locale, DefaultAzureCredential eseguirà una ricerca in una catena di credenziali per le prime credenziali disponibili. Se è Managed_Identity_Client_ID Null in locale, userà automaticamente le credenziali dell'interfaccia della riga di comando di Azure locale o dell'accesso a Visual Studio. Altre informazioni su questo processo sono disponibili nella panoramica della libreria di identità di Azure.
Quando l'applicazione viene distribuita in Azure, DefaultAzureCredential recupera automaticamente la Managed_Identity_Client_ID variabile dall'ambiente del servizio app. Tale valore diventa disponibile quando un'identità gestita è associata all'app.
Questo processo complessivo garantisce che l'app possa essere eseguita in modo sicuro in locale e in Azure senza la necessità di apportare modifiche al codice.
Connessione più app che usano più identità gestite
Anche se le app nell'esempio precedente hanno condiviso tutti gli stessi requisiti di accesso ai servizi, gli ambienti reali sono spesso più sfumati. Si consideri uno scenario in cui più app si connettono agli stessi account di archiviazione, ma due delle app accedono anche a servizi o database diversi.
Per configurare questa configurazione nel codice, assicurarsi che l'applicazione registri servizi separati per connettersi a ogni account di archiviazione o database. Assicurarsi di eseguire il pull degli ID client dell'identità gestita corretti per ogni servizio durante la configurazione di DefaultAzureCredential. Nell'esempio di codice seguente vengono configurate le connessioni al servizio seguenti:
Due connessioni a account di archiviazione separati tramite un'identità gestita assegnata dall'utente condiviso
Una connessione ad Azure Cosmos DB e ai servizi SQL di Azure usando una seconda identità gestita assegnata dall'utente condiviso
// Get the first user-assigned managed identity ID to connect to shared storage
const clientIdStorage = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID_Storage");
// First blob storage client that using a managed identity
BlobServiceClient blobServiceClient = new BlobServiceClient(
new Uri("https://<receipt-storage-account>.blob.core.windows.net"),
new DefaultAzureCredential()
{
ManagedIdentityClientId = clientIDstorage
});
// Second blob storage client that using a managed identity
BlobServiceClient blobServiceClient2 = new BlobServiceClient(
new Uri("https://<contract-storage-account>.blob.core.windows.net"),
new DefaultAzureCredential()
{
ManagedIdentityClientId = clientIDstorage
});
// Get the second user-assigned managed identity ID to connect to shared databases
var clientIDdatabases = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID_Databases");
// Create an Azure Cosmos DB client
CosmosClient client = new CosmosClient(
accountEndpoint: Environment.GetEnvironmentVariable("COSMOS_ENDPOINT", EnvironmentVariableTarget.Process),
new DefaultAzureCredential()
{
ManagedIdentityClientId = clientIDdatabases
});
// Open a connection to Azure SQL using a managed identity
string ConnectionString1 = @"Server=<azure-sql-hostname>.database.windows.net; User Id=ClientIDOfTheManagedIdentity; Authentication=Active Directory Default; Database=<database-name>";
using (SqlConnection conn = new SqlConnection(ConnectionString1))
{
conn.Open();
}
class Demo {
public static void main(String[] args) {
// Get the first user-assigned managed identity ID to connect to shared storage
String clientIdStorage = System.getenv("Managed_Identity_Client_ID_Storage");
// Get the DefaultAzureCredential from clientIdStorage
DefaultAzureCredential storageCredential =
new DefaultAzureCredentialBuilder().managedIdentityClientId(clientIdStorage).build();
// First blob storage client that using a managed identity
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<receipt-storage-account>.blob.core.windows.net")
.credential(storageCredential)
.buildClient();
// Second blob storage client that using a managed identity
BlobServiceClient blobServiceClient2 = new BlobServiceClientBuilder()
.endpoint("https://<contract-storage-account>.blob.core.windows.net")
.credential(storageCredential)
.buildClient();
// Get the second user-assigned managed identity ID to connect to shared databases
String clientIdDatabase = System.getenv("Managed_Identity_Client_ID_Databases");
// Create an Azure Cosmos DB client
CosmosClient cosmosClient = new CosmosClientBuilder()
.endpoint("https://<cosmos-db-account>.documents.azure.com:443/")
.credential(new DefaultAzureCredentialBuilder().managedIdentityClientId(clientIdDatabase).build())
.buildClient();
// Open a connection to Azure SQL using a managed identity
String connectionUrl = "jdbc:sqlserver://<azure-sql-hostname>.database.windows.net:1433;"
+ "database=<database-name>;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database"
+ ".windows.net;loginTimeout=30;Authentication=ActiveDirectoryMSI;";
try {
Connection connection = DriverManager.getConnection(connectionUrl);
Statement statement = connection.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
All'interno del progetto usare npm per aggiungere un riferimento al @azure/identity pacchetto. Questa libreria contiene tutte le entità necessarie per implementare DefaultAzureCredential. Installare tutte le altre librerie di Azure SDK rilevanti per l'app.
Nella parte superiore del index.js file aggiungere le istruzioni seguenti import per importare le classi client necessarie per i servizi a cui si connetterà l'app:
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";
import { KeyClient } from "@azure/keyvault-keys";
All'interno del index.js file creare oggetti client per i servizi di Azure a cui si connetterà l'app. Gli esempi seguenti si connettono a blob Archiviazione, Cosmos DB e Azure SQL usando le classi SDK corrispondenti.
// Get the first user-assigned managed identity ID to connect to shared storage
const clientIdStorage = process.env.MANAGED_IDENTITY_CLIENT_ID_STORAGE;
// Storage account names
const storageAccountName1 = process.env.AZURE_STORAGE_ACCOUNT_NAME_1;
const storageAccountName2 = process.env.AZURE_STORAGE_ACCOUNT_NAME_2;
// First blob storage client that using a managed identity
const blobServiceClient = new BlobServiceClient(
`https://${storageAccountName1}.blob.core.windows.net`,
new DefaultAzureCredential({
managedIdentityClientId: clientIdStorage
})
);
// Second blob storage client that using a managed identity
const blobServiceClient2 = new BlobServiceClient(
`https://${storageAccountName2}.blob.core.windows.net`,
new DefaultAzureCredential({
managedIdentityClientId: clientIdStorage
})
);
// Get the second user-assigned managed identity ID to connect to shared databases
const clientIdDatabases = process.env.MANAGED_IDENTITY_CLIENT_ID_DATABASES;
// Cosmos DB Account endpoint
const cosmosDbAccountEndpoint = process.env.COSMOS_ENDPOINT;
// Create an Azure Cosmos DB client
const client = new CosmosClient({
endpoint: cosmosDbAccountEndpoint,
credential: new DefaultAzureCredential({
managedIdentityClientId: clientIdDatabases
})
});
// Open a connection to Azure SQL using a managed identity with mssql package
// mssql reads the environment variables to get the managed identity
const server = process.env.AZURE_SQL_SERVER;
const database = process.env.AZURE_SQL_DATABASE;
const port = parseInt(process.env.AZURE_SQL_PORT);
const type = process.env.AZURE_SQL_AUTHENTICATIONTYPE;
const config = {
server,
port,
database,
authentication: {
type // <---- Passwordless connection
},
options: {
encrypt: true
}
};
await sql.connect(sqlConfig);
È anche possibile associare un'identità gestita assegnata dall'utente e un'identità gestita assegnata dal sistema a una risorsa contemporaneamente. Ciò può essere utile negli scenari in cui tutte le app richiedono l'accesso agli stessi servizi condivisi, ma una delle app ha anche una dipendenza molto specifica da un servizio aggiuntivo. L'uso di un'identità assegnata dal sistema garantisce anche che l'identità associata a tale app specifica venga eliminata quando l'app viene eliminata, che può contribuire a mantenere pulito l'ambiente.
Questi tipi di scenari vengono esaminati in modo più approfondito nelle raccomandazioni sulle procedure consigliate per le identità.
Passaggi successivi
In questa esercitazione si è appreso come eseguire la migrazione di un'applicazione a connessioni senza password. È possibile leggere le risorse seguenti per esplorare i concetti illustrati in questo articolo in modo più approfondito: