Los recursos de Azure con compatibilidad con identidades administradas siempre incluyen una opción para especificar una identidad administrada con la que conectarse a los recursos de Azure que admiten la autenticación de Microsoft Entra. La compatibilidad con identidades administradas hace que los desarrolladores no necesiten administrar credenciales en el código. Las identidades administradas son la opción de autenticación recomendada cuando se trabaja con recursos de Azure que las admitan. Lea la introducción a la identidades administradas.
En esta página se muestra cómo configurar una instancia de App Service para que pueda conectarse a Azure Key Vault, Azure Storage y Microsoft SQL Server. Se pueden usar los mismos principios para cualquier recurso de Azure que admita identidades administradas y que se conecte a los recursos que admitan la autenticación de Microsoft Entra.
Los ejemplos de código usan la biblioteca cliente de Identidad de Azure, que es el método recomendado, ya que administra automáticamente muchos de los pasos, incluida la adquisición de un token de acceso que se utiliza en la conexión.
¿A qué recursos se pueden conectar las identidades administradas?
Una identidad administrada puede conectarse a cualquier recurso que admita la autenticación de Microsoft Entra. En general, no se requiere una compatibilidad especial para que el recurso permita que las identidades administradas se conecten a él.
Algunos recursos no admiten la autenticación de Microsoft Entra o su biblioteca cliente no admite la autenticación con un token. Siga leyendo para ver nuestras instrucciones sobre cómo usar una identidad administrada para acceder de forma segura a las credenciales sin necesidad de almacenarlas en el código o la configuración de la aplicación.
Creación de identidades administradas
Hay dos tipos de identidades administradas: asignadas por el sistema y asignadas por el usuario. Las identidades asignadas por el sistema están vinculadas directamente a un único recurso de Azure. Cuando se elimina el recurso de Azure, también se elimina la identidad. Una identidad administrada asignada por el usuario se puede asociar a varios recursos de Azure, y su ciclo de vida es independiente de esos recursos.
Le recomendamos usar una identidad administrada asignada por el usuario para la mayoría de casos. Si el recurso de origen que utiliza no admite identidades administradas asignadas por el usuario, debe consultar la documentación del proveedor de ese recurso para aprender a configurarlo y que tenga una identidad administrada asignada por el sistema.
Importante
La cuenta usada para crear identidades administradas necesita un rol del tipo "Colaborador de identidad administrada" para crear una nueva identidad administrada asignada por el usuario.
Cree una identidad administrada asignada por el usuario mediante la opción preferida:
Después de crear una identidad administrada asignada por el usuario, anote los valores clientId
y principalId
que se devuelven cuando se crea la identidad administrada. Usará principalId
al agregar permisos y clientId
en el código de la aplicación.
Para poder usar la identidad administrada en el código, tenemos que asignarla a la instancia de App Service que la usará. Para el proceso de configuración de una instancia de App Service que sirve para usar una identidad administrada asignada por el usuario es necesario que indique el identificador de recursos de la identidad administrada en la configuración de la aplicación.
Incorporación de permisos a la identidad
Una vez que haya configurado App Service para que use una identidad administrada asignada por el usuario, conceda los permisos necesarios a la identidad. En esta situación, estamos usando esta identidad para interactuar con Azure Storage, por lo que debe usar el sistema de Control de acceso basado en roles (RBAC) de Azure para conceder permisos de identidad administrada asignada por el usuario al recurso.
Importante
Necesitará un rol como "Administrador de acceso de usuario" o "Propietario" para el recurso de destino a fin de agregar asignaciones de roles. Asegúrese de conceder los privilegios mínimos necesarios para que se ejecute la aplicación.
Para los recursos a los que desea acceder es necesario que conceda los permisos de identidad. Por ejemplo, si solicita un token para acceder a Key Vault, también debe agregar una directiva de acceso que incluya la identidad administrada de la aplicación o la función. De lo contrario, las llamadas a Key Vault se rechazarán, incluso si usa un token válido. Lo mismo se aplica a Azure SQL Database. Para obtener más información sobre los recursos que admiten tokens de Microsoft Entra, consulte Servicios de Azure que admiten autenticación de Microsoft Entra.
Uso de identidades administradas en el código
Después de completar los pasos descritos anteriormente, App Service tendrá una identidad administrada con permisos para un recurso de Azure. Puede usar la identidad administrada para obtener un token de acceso que el código puede usar para interactuar con los recursos de Azure, en lugar de almacenar las credenciales en el código.
Se recomienda usar las bibliotecas cliente que proporcionamos para su lenguaje de programación preferido. Estas bibliotecas adquieren tokens de acceso para usted, lo que facilita la autenticación con el identificador de Microsoft Entra. Para más información, consulte Bibliotecas de cliente para la autenticación de identidades administradas.
Uso de una biblioteca de identidades de Azure para acceder a los recursos de Azure
Cada una de las bibliotecas de Identidad de Azure proporciona un tipo de DefaultAzureCredential
. DefaultAzureCredential
intenta autenticar automáticamente al usuario a través de flujos diferentes, incluidas las variables de entorno o un inicio de sesión interactivo. El tipo de credencial se puede usar en un entorno de desarrollo con sus propias credenciales. También se puede utilizar en el entorno de producción de Azure mediante una identidad administrada. No se requieren cambios en el código al implementar la aplicación.
Si usa identidades administradas asignadas por el usuario, también debe especificar explícitamente la identidad administrada asignada por el usuario con la que desea autenticarse pasando el identificador de cliente de la identidad como parámetro. Para recuperar el identificador de cliente, vaya a la identidad en Azure Portal.
Acceso a un blob en Azure Storage
using Azure.Identity;
using Azure.Storage.Blobs;
// code omitted for brevity
// Specify the Client ID if using user-assigned managed identities
var clientID = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID");
var credentialOptions = new DefaultAzureCredentialOptions
{
ManagedIdentityClientId = clientID
};
var credential = new DefaultAzureCredential(credentialOptions);
var blobServiceClient1 = new BlobServiceClient(new Uri("<URI of Storage account>"), credential);
BlobContainerClient containerClient1 = blobServiceClient1.GetBlobContainerClient("<name of blob>");
BlobClient blobClient1 = containerClient1.GetBlobClient("<name of file>");
if (blobClient1.Exists())
{
var downloadedBlob = blobClient1.Download();
string blobContents = downloadedBlob.Value.Content.ToString();
}
import com.azure.identity.DefaultAzureCredential;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
// read the Client ID from your environment variables
String clientID = System.getProperty("Client_ID");
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
.managedIdentityClientId(clientID)
.build();
BlobServiceClient blobStorageClient = new BlobServiceClientBuilder()
.endpoint("<URI of Storage account>")
.credential(credential)
.buildClient();
BlobContainerClient blobContainerClient = blobStorageClient.getBlobContainerClient("<name of blob container>");
BlobClient blobClient = blobContainerClient.getBlobClient("<name of blob/file>");
if (blobClient.exists()) {
String blobContent = blobClient.downloadContent().toString();
}
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";
// Specify the Client ID if using user-assigned managed identities
const clientID = process.env.Managed_Identity_Client_ID;
const credential = new DefaultAzureCredential({
managedIdentityClientId: clientID
});
const blobServiceClient = new BlobServiceClient("<URI of Storage account>", credential);
const containerClient = blobServiceClient.getContainerClient("<name of blob>");
const blobClient = containerClient.getBlobClient("<name of file>");
async function downloadBlob() {
if (await blobClient.exists()) {
const downloadBlockBlobResponse = await blobClient.download();
const downloadedBlob = await streamToString(downloadBlockBlobResponse.readableStreamBody);
console.log("Downloaded blob content:", downloadedBlob);
}
}
async function streamToString(readableStream) {
return new Promise((resolve, reject) => {
const chunks = [];
readableStream.on("data", (data) => {
chunks.push(data.toString());
});
readableStream.on("end", () => {
resolve(chunks.join(""));
});
readableStream.on("error", reject);
});
}
downloadBlob().catch(console.error);
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient
import os
# Specify the Client ID if using user-assigned managed identities
client_id = os.getenv("Managed_Identity_Client_ID")
credential = DefaultAzureCredential(managed_identity_client_id=client_id)
blob_service_client = BlobServiceClient(account_url="<URI of Storage account>", credential=credential)
container_client = blob_service_client.get_container_client("<name of blob>")
blob_client = container_client.get_blob_client("<name of file>")
def download_blob():
if blob_client.exists():
download_stream = blob_client.download_blob()
blob_contents = download_stream.readall().decode('utf-8')
print("Downloaded blob content:", blob_contents)
download_blob()
package main
import (
"context"
"fmt"
"io"
"os"
"strings"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)
func main() {
// The client ID for the user-assigned managed identity is read from the AZURE_CLIENT_ID env var
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
fmt.Printf("failed to obtain a credential: %v\n", err)
return
}
accountURL := "<URI of Storage account>"
containerName := "<name of blob>"
blobName := "<name of file>"
serviceClient, err := azblob.NewServiceClient(accountURL, cred, nil)
if err != nil {
fmt.Printf("failed to create service client: %v\n", err)
return
}
containerClient := serviceClient.NewContainerClient(containerName)
blobClient := containerClient.NewBlobClient(blobName)
// Check if the blob exists
_, err = blobClient.GetProperties(context.Background(), nil)
if err != nil {
fmt.Printf("failed to get blob properties: %v\n", err)
return
}
// Download the blob
downloadResponse, err := blobClient.Download(context.Background(), nil)
if err != nil {
fmt.Printf("failed to download blob: %v\n", err)
return
}
// Read the blob content
blobData := downloadResponse.Body(nil)
defer blobData.Close()
blobContents := new(strings.Builder)
_, err = io.Copy(blobContents, blobData)
if err != nil {
fmt.Printf("failed to read blob data: %v\n", err)
return
}
fmt.Println("Downloaded blob content:", blobContents.String())
}
Acceso a un secreto almacenado en Azure Key Vault
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Azure.Core;
// code omitted for brevity
// Specify the Client ID if using user-assigned managed identities
var clientID = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID");
var credentialOptions = new DefaultAzureCredentialOptions
{
ManagedIdentityClientId = clientID
};
var credential = new DefaultAzureCredential(credentialOptions);
var client = new SecretClient(
new Uri("https://<your-unique-key-vault-name>.vault.azure.net/"),
credential);
KeyVaultSecret secret = client.GetSecret("<my secret>");
string secretValue = secret.Value;
import com.azure.core.util.polling.SyncPoller;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import com.azure.security.keyvault.secrets.models.DeletedSecret;
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
String keyVaultName = "mykeyvault";
String keyVaultUri = "https://" + keyVaultName + ".vault.azure.net";
String secretName = "mysecret";
// read the user-assigned managed identity Client ID from your environment variables
String clientID = System.getProperty("Managed_Identity_Client_ID");
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
.managedIdentityClientId(clientID)
.build();
SecretClient secretClient = new SecretClientBuilder()
.vaultUrl(keyVaultUri)
.credential(credential)
.buildClient();
KeyVaultSecret retrievedSecret = secretClient.getSecret(secretName);
import { DefaultAzureCredential } from "@azure/identity";
import { SecretClient } from "@azure/keyvault-secrets";
// Specify the Client ID if using user-assigned managed identities
const clientID = process.env.Managed_Identity_Client_ID;
const credential = new DefaultAzureCredential({
managedIdentityClientId: clientID
});
const client = new SecretClient("https://<your-key-vault-name>.vault.azure.net/", credential);
async function getSecret() {
const secret = await client.getSecret("<your-secret-name>");
const secretValue = secret.value;
console.log(secretValue);
}
getSecret().catch(err => console.error("Error retrieving secret:", err));
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
import os
# Specify the Client ID if using user-assigned managed identities
client_id = os.getenv("Managed_Identity_Client_ID")
credential = DefaultAzureCredential(managed_identity_client_id=client_id)
client = SecretClient(vault_url="https://<your-key-vault-name>.vault.azure.net/", credential=credential)
def get_secret():
secret = client.get_secret("<your-secret-name>")
secret_value = secret.value
print(secret_value)
if __name__ == "__main__":
try:
get_secret()
except Exception as e:
print(f"Error retrieving secret: {e}")
package main
import (
"context"
"fmt"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
)
func main() {
// The client ID for the user-assigned managed identity is read from the AZURE_CLIENT_ID env var
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
fmt.Printf("failed to obtain a credential: %v\n", err)
return
}
client, err := azsecrets.NewClient("https://<your-key-vault-name>.vault.azure.net/", credential, nil)
if err != nil {
fmt.Printf("Failed to create secret client: %v\n", err)
return
}
secretResp, err := client.GetSecret(context.TODO(), "<your-secret-name>", nil)
if err != nil {
fmt.Printf("Failed to get secret: %v\n", err)
return
}
secretValue := *secretResp.Value
fmt.Println(secretValue)
}
Acceso a Azure SQL Database
using Azure.Identity;
using Microsoft.Data.SqlClient;
// code omitted for brevity
// Specify the Client ID if using user-assigned managed identities
var clientID = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID");
var credentialOptions = new DefaultAzureCredentialOptions
{
ManagedIdentityClientId = clientID
};
AccessToken accessToken = await new DefaultAzureCredential(credentialOptions).GetTokenAsync(
new TokenRequestContext(new string[] { "https://database.windows.net//.default" }));
using var connection = new SqlConnection("Server=<DB Server>; Database=<DB Name>;")
{
AccessToken = accessToken.Token
};
var cmd = new SqlCommand("select top 1 ColumnName from TableName", connection);
await connection.OpenAsync();
SqlDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
Console.WriteLine(dr.GetValue(0).ToString());
}
dr.Close();
Si usa Azure Spring Apps, puede conectarse a Azure SQL Databases con una identidad administrada sin necesidad de realizar cambios en el código.
Abra el archivo src/main/resources/application.properties
y agregue Authentication=ActiveDirectoryMSI;
en la parte final de la siguiente línea. Asegúrese de usar el valor correcto para la variable $AZ_DATABASE_NAME
.
spring.datasource.url=jdbc:sqlserver://$AZ_DATABASE_NAME.database.windows.net:1433;database=demo;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;Authentication=ActiveDirectoryMSI;
Más información sobre cómo usar una identidad administrada para conectar Azure SQL Database a una aplicación de Azure Spring Apps.
import { DefaultAzureCredential } from "@azure/identity";
import { Connection, Request } from "tedious";
// Specify the Client ID if using a user-assigned managed identity
const clientID = process.env.Managed_Identity_Client_ID;
const credential = new DefaultAzureCredential({
managedIdentityClientId: clientID
});
async function getAccessToken() {
const tokenResponse = await credential.getToken("https://database.windows.net//.default");
return tokenResponse.token;
}
async function queryDatabase() {
const accessToken = await getAccessToken();
const config = {
server: "<your-server-name>",
authentication: {
type: "azure-active-directory-access-token",
options: {
token: accessToken
}
},
options: {
database: "<your-database-name>",
encrypt: true
}
};
const connection = new Connection(config);
connection.on("connect", err => {
if (err) {
console.error("Connection failed:", err);
return;
}
const request = new Request("SELECT TOP 1 ColumnName FROM TableName", (err, rowCount, rows) => {
if (err) {
console.error("Query failed:", err);
return;
}
rows.forEach(row => {
console.log(row.value);
});
connection.close();
});
connection.execSql(request);
});
connection.connect();
}
queryDatabase().catch(err => console.error("Error:", err));
import os
from azure.identity import DefaultAzureCredential
from azure.core.credentials import AccessToken
import pyodbc
# Specify the Client ID if using a user-assigned managed identity
client_id = os.getenv("Managed_Identity_Client_ID")
credential = DefaultAzureCredential(managed_identity_client_id=client_id)
# Get the access token
token = credential.get_token("https://database.windows.net//.default")
access_token = token.token
# Set up the connection string
connection_string = "Driver={ODBC Driver 18 for SQL Server};Server=<your-server-name>;Database=<your-database-name>;"
# Connect to the database
connection = pyodbc.connect(connection_string, attrs_before={"AccessToken": access_token})
# Execute the query
cursor = connection.cursor()
cursor.execute("SELECT TOP 1 ColumnName FROM TableName")
# Fetch and print the result
row = cursor.fetchone()
while row:
print(row)
row = cursor.fetchone()
# Close the connection
cursor.close()
connection.close()
package main
import (
"context"
"database/sql"
"fmt"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/denisenkom/go-mssqldb"
)
func main() {
// The client ID for the user-assigned managed identity is read from the AZURE_CLIENT_ID env var
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
fmt.Printf("failed to obtain a credential: %v\n", err)
return
}
// Get the access token
token, err := credential.GetToken(context.TODO(), azidentity.TokenRequestOptions{
Scopes: []string{"https://database.windows.net//.default"},
})
if err != nil {
fmt.Printf("Failed to get token: %v\n", err)
return
}
// Set up the connection string
connString := fmt.Sprintf("sqlserver://<your-server-name>?database=<your-database-name>&access_token=%s", token.Token)
// Connect to the database
db, err := sql.Open("sqlserver", connString)
if err != nil {
fmt.Printf("Failed to connect to the database: %v\n", err)
return
}
defer db.Close()
// Execute the query
rows, err := db.QueryContext(context.TODO(), "SELECT TOP 1 ColumnName FROM TableName")
if err != nil {
fmt.Printf("Failed to execute query: %v\n", err)
return
}
defer rows.Close()
// Fetch and print the result
for rows.Next() {
var columnValue string
if err := rows.Scan(&columnValue); err != nil {
fmt.Printf("Failed to scan row: %v\n", err)
return
}
fmt.Println(columnValue)
}
}
Uso de la Biblioteca de autenticación de Microsoft (MSAL) para acceder a los recursos de Azure
Además de las bibliotecas de identidad de Azure, también puede usar MSAL para acceder a los recursos de Azure mediante identidades administradas. Los fragmentos de código siguientes muestran cómo usar MSAL para acceder a los recursos de Azure en varios lenguajes de programación.
En el caso de las identidades administradas asignadas por el sistema, el desarrollador no necesita pasar ninguna información adicional. MSAL deduce automáticamente los metadatos pertinentes sobre la identidad asignada. En el caso de las identidades administradas asignadas por el usuario, el desarrollador debe pasar el identificador de cliente, el identificador de recurso completo o el identificador de objeto de la identidad administrada.
A continuación, puede adquirir un token para acceder a un recurso. Antes de usar identidades administradas, los desarrolladores deben habilitarlas para los recursos que quieren usar.
using Microsoft.Identity.Client;
using System;
string resource = "https://vault.azure.net";
// Applies to system-assigned managed identities only
IManagedIdentityApplication mi = ManagedIdentityApplicationBuilder.Create(ManagedIdentityId.SystemAssigned)
.Build();
// Applies to user-assigned managed identities only
string userAssignedManagedIdentityClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
IManagedIdentityApplication mi = ManagedIdentityApplicationBuilder.Create(ManagedIdentityId.WithUserAssignedClientId(userAssignedManagedIdentityClientId))
.Build();
// Acquire token
AuthenticationResult result = await mi.AcquireTokenForManagedIdentity(resource)
.ExecuteAsync()
.ConfigureAwait(false);
if (!string.IsNullOrEmpty(result.AccessToken))
{
Console.WriteLine(result.AccessToken);
}
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.ManagedIdentityApplication;
import com.microsoft.aad.msal4j.ManagedIdentityId;
import com.microsoft.aad.msal4j.ManagedIdentityParameters;
String resource = "https://vault.azure.net";
// Use this for user-assigned managed identities
private static final String USER_ASSIGNED_MI_CLIENT_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
// Use this for system-assigned managed identities
ManagedIdentityApplication miApp = ManagedIdentityApplication
.builder(ManagedIdentityId.systemAssigned())
.build();
// Use this for user-assigned managed identities
ManagedIdentityApplication miApp = ManagedIdentityApplication
.builder(ManagedIdentityId.userAssignedClientId(USER_ASSIGNED_MI_CLIENT_ID))
.build();
// Acquire token
IAuthenticationResult result = miApp.acquireTokenForManagedIdentity(
ManagedIdentityParameters.builder(resource)
.build()).get();
System.out.println(result.accessToken());
import {
LogLevel,
LoggerOptions,
AuthenticationResult,
} from "@azure/msal-common";
import {
ManagedIdentityRequestParams,
ManagedIdentityConfiguration,
ManagedIdentityApplication,
ManagedIdentityIdParams,
NodeSystemOptions,
} from "@azure/msal-node";
// Define resource
const managedIdentityRequestParams: ManagedIdentityRequestParams = {
resource: "https://vault.azure.net",
};
// This section applies to user-assigned managed identities only
const userAssignedManagedIdentityIdParams: ManagedIdentityIdParams = {
userAssignedClientId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
};
const userAssignedManagedIdentityConfig: ManagedIdentityConfiguration = {
userAssignedManagedIdentityIdParams, // applicable to user-assigned managed identities only
// optional for logging
system: {
loggerOptions: {
logLevel: LogLevel.Verbose,
} as LoggerOptions,
} as NodeSystemOptions,
};
const userSystemAssignedManagedIdentityApplication: ManagedIdentityApplication =
new ManagedIdentityApplication(userAssignedManagedIdentityConfig);
// Acquire token: user-assigned managed identity
const response: AuthenticationResult =
await userAssignedManagedIdentityApplication.acquireToken(
managedIdentityRequestParams
);
// This section applies to system-assigned managed identities only
const systemAssignedManagedIdentityConfig: ManagedIdentityConfiguration = {
// optional for logging
system: {
loggerOptions: {
logLevel: LogLevel.Verbose,
} as LoggerOptions,
} as NodeSystemOptions,
};
const systemAssignedManagedIdentityApplication: ManagedIdentityApplication =
new ManagedIdentityApplication(systemAssignedManagedIdentityConfig);
// Acquire token: system-assigned managed identity
const response: AuthenticationResult =
await systemAssignedManagedIdentityApplication.acquireToken(
managedIdentityRequestParams
);
console.log(response);
import msal
import requests
# Use this for system-assigned managed identities
managed_identity = msal.SystemAssignedManagedIdentity()
# Use this for user-assigned managed identities
userAssignedClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
managed_identity = msal.UserAssignedManagedIdentity(client_id=userAssignedClientId)
global_app = msal.ManagedIdentityClient(managed_identity, http_client=requests.Session())
result = global_app.acquire_token_for_client(resource='https://vault.azure.net')
if "access_token" in result:
print("Token obtained!")
import (
"context"
"fmt"
"net/http"
mi "github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity"
)
func RunManagedIdentity() {
// Use this for system-assigned managed identities
miSystemAssigned, err := mi.New(mi.SystemAssigned())
if err != nil {
fmt.Println(err)
}
result, err := miSystemAssigned.AcquireToken(context.TODO(), "https://management.azure.com")
if err != nil {
fmt.Println(err)
}
// Use this for user-assigned managed identities with a client ID.
miClientIdUserAssigned, err := mi.New(mi.ClientID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"))
if err != nil {
fmt.Println(err)
}
result, err := miClientIdUserAssigned.AcquireToken(context.TODO(), "https://management.azure.com")
// Print out token expiry time
fmt.Println("token expire at : ", result.ExpiresOn)
}
Conexión a recursos que no admiten la autenticación de Microsoft Entra o basada en tokens en las bibliotecas
Algunos recursos de Azure no admiten aún la autenticación de Microsoft Entra o sus bibliotecas cliente no admiten la autenticación con un token. Normalmente, estos recursos son tecnologías de código abierto que esperan un nombre de usuario y una contraseña o una clave de acceso en una cadena de conexión.
Para evitar almacenar las credenciales en el código o la configuración de la aplicación, puede almacenar las credenciales como un secreto en Azure Key Vault. Con el ejemplo mostrado anteriormente, puede recuperar el secreto de Azure Key Vault mediante una identidad administrada y pasar las credenciales a la cadena de conexión. Este enfoque significa que no es necesario administrar las credenciales directamente en el código o el entorno. Para obtener un ejemplo detallado, consulte Uso de identidades administradas para acceder a certificados de Azure Key Vault. Para más información sobre la autenticación de Azure Key Vault, consulte Autenticación de Azure Key Vault.
Instrucciones en caso de administrar tokens directamente
En algunos escenarios, es posible que quiera adquirir tokens para identidades administradas manualmente en lugar de usar un método integrado para conectarse al recurso de destino. Estos escenarios no incluyen ninguna biblioteca cliente para el lenguaje de programación que está utilizando o el recurso de destino al que se está conectando o al conectarse a recursos que no se ejecutan en Azure. Al adquirir tokens manualmente, se proporcionan las siguientes directrices:
Almacenamiento en caché de los tokens adquiridos
Para mejorar el rendimiento y la confiabilidad, se recomienda que la aplicación almacene en caché los tokens en la memoria local o cifrados si desea guardarlos en el disco. Como los tokens de identidad administrada son válidos durante 24 horas, no hay ninguna ventaja en solicitar nuevos tokens con regularidad, ya que se devolverá uno almacenado en caché desde el punto de conexión de emisión de tokens. Si supera los límites de solicitud, se le limitará la velocidad y recibirá un error HTTP 429.
Al adquirir un token, puede establecer la caché de tokens para que expire 5 minutos antes de la expires_on
(o propiedad equivalente) que se devolverá cuando se genere el token.
Inspección de tokens
La aplicación no se debe basar en el contenido de un token. El contenido del token está pensado solo para la audiencia (recurso de destino) a la que se accede, no para el cliente que solicita el token. El contenido del token puede cambiar o cifrarse en el futuro.
No exponer ni mover tokens
Los tokens deben tratarse como credenciales. No los exponga a usuarios u otros servicios; por ejemplo, soluciones de registro y supervisión. No se deben mover desde el recurso de origen que los usa, excepto para autenticarse en el recurso de destino.
Pasos siguientes