具有受控識別支援的 Azure 資源一律會提供選項來指定受控識別,以連線到支援 Microsoft Entra 驗證的 Azure 資源。 受控識別支援可讓開發人員不需要在程式碼中管理認證。 使用支援受控識別的 Azure 資源時,受控識別是建議的驗證選項。
閱讀受控識別的概觀。
此頁面示範如何設定 App Service,使其可以連線到 Azure Key Vault、Azure 儲存體和 Microsoft SQL Server。 相同的準則可以應用於任何支援受控識別的 Azure 資源,以及連接支援 Microsoft Entra 認證的資源。
程式碼範例會使用 Azure 身分識別用戶端程式庫,這是建議的方法,因為其會自動為您處理許多步驟,包括取得連線中使用的存取權杖。
受控識別可以連線到哪些資源?
受控識別可以連線到支援 Microsoft Entra 驗證的任何資源。 一般而言,資源不需要特殊支援,即可允許受控識別連線至其中。
某些資源不支援 Microsoft Entra 驗證,或其用戶端程式庫不支援使用權杖進行驗證。 請繼續閱讀,以了解如何使用受控識別安全地存取認證,而不需要將其儲存在程式碼或應用程式設定中。
建立受控識別
有兩種受控識別:系統指派和使用者指派。 系統指派的身分識別會直接連結到單一 Azure 資源。 刪除 Azure 資源時,也會刪除身分識別。 使用者指派的受控識別可以與多個 Azure 資源相關聯,而且其生命週期與這些資源無關。
對於大多數情況,我們建議您使用使用者指派的受控識別。 如果您使用的來源資源不支援使用者指派的受控識別,則您應該參考該資源提供者的文件,了解如何將其設定為具有系統指派的受控識別。
重要
用於建立受控識別的帳戶需要「受控識別參與者」之類的角色,才能建立新的使用者指派的受控識別。
使用您偏好的選項來建立使用者指派的受控識別:
建立使用者指派的受控識別之後,請記下建立受控識別時傳回的 clientId
和 principalId
值。 您在新增權限時使用 principalId
,並在應用程式的程式碼中使用 clientId
。
在您可以在程式碼中使用受控識別之前,我們必須將其指派給將使用它的應用程式服務。 將應用程式服務設定為使用使用者指派的受控識別的程序要求您在應用程式設定中指定受控識別的資源識別碼。
將權限新增至身分識別
將應用程式服務設定為使用使用者指派的受控識別後,向該識別授與必要的權限。 在此案例中,我們會使用此身分識別來與 Azure 儲存體互動,因此您需要使用 Azure 角色型存取控制 (RBAC) 系統,來將使用者指派的受控識別權限授與資源。
重要
您將需要「使用者存取管理員」或「擁有者」等角色,才能在目標資源中新增角色指派。 請確定您授與執行應用程式所需的最低權限。
您想要存取的任何資源都需要您授與身分識別權限。 例如,若您要求令牌以存取 Key Vault,則須新增一個存取原則,其中包含應用程式或函數中的受控識別。 否則即使呼叫 Key Vault 時使用有效權杖,仍將遭拒絕。 對 Azure SQL Database 而言,也是如此。 若要深入瞭解哪些資源支援 Microsoft Entra 權杖,請參閱支援 Microsoft Entra 驗證的 Azure 服務。
在您的程式碼中使用受控識別
完成上述步驟之後,您的應用程式服務擁有具有 Azure 資源權限的受控識別。 您可以使用受控識別來取得存取權杖,您的程式碼可使用該權杖與 Azure 資源互動,而不是將認證儲存在您的程式碼中。
建議您使用我們針對您慣用的程式設計語言提供的客戶端連結庫。 這些連結庫會為您取得存取令牌,讓您輕鬆地使用 Microsoft Entra 識別碼進行驗證。 如需詳細資訊,請參閱 受控識別驗證的用戶端連結庫。
使用 Azure 身分識別連結庫來存取 Azure 資源
每個 Azure 身分識別程式庫都提供 DefaultAzureCredential
類型。
DefaultAzureCredential
嘗試透過不同的流程自動驗證使用者,包括環境變數或互動式登入。 認證類型可以搭配您自己的認證在開發環境中使用。 其也可以利用受控識別,在 Azure 實際執行環境中使用。 當您部署應用程式時,不需要變更任何程式碼。
如果您使用的是使用者指派的受控識別,則應明確指定您希望用來驗證的使用者指派受控識別,並將其用戶端識別碼作為參數傳遞。 您可以瀏覽至 Azure 入口網站中的識別項目來擷取用戶端識別碼。
存取 Azure 儲存體中的 Blob
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())
}
存取 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)
}
存取 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();
如果您使用 Azure Spring Apps,則可以使用受控識別連線到 Azure SQL 資料庫,而無需對您的程式碼進行任何變更。
開啟 src/main/resources/application.properties
檔案,並在下一行結尾新增 Authentication=ActiveDirectoryMSI;
。 請務必針對 $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;
深入閱讀如何使用受控識別將 Azure SQL Database 連線至 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)
}
}
使用 Microsoft 驗證連結庫 (MSAL) 來存取 Azure 資源
除了 Azure 身分識別連結庫,您也可以使用 MSAL 來使用受控識別來存取 Azure 資源。 下列代碼段示範如何使用 MSAL 來存取各種程式設計語言的 Azure 資源。
針對系統指派的受控識別,開發人員不需要傳遞任何其他資訊。 MSAL 會自動判斷指派身分的相關元數據。 針對使用者指派的受控識別,開發人員必須傳遞用戶端標識碼、完整資源標識碼或受控識別的物件標識符。
然後,您可以取得令牌來存取資源。 在使用受控識別之前,開發人員必須為他們想要使用的資源啟用該功能。
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)
}
連線到程式庫中不支援 Microsoft Entra ID 或權杖型驗證的資源
某些 Azure 資源尚未支援 Microsoft Entra 驗證,或其用戶端程式庫不支援使用權杖進行驗證。 這些資源通常是開放原始碼技術,預期連接字串中有使用者名稱和密碼或存取金鑰。
若要避免將認證儲存在您的程式碼或應用程式設定中,您可以將認證當作祕密儲存在 Azure Key Vault 中。 使用上面顯示的範例,您可以使用受控識別從 Azure Key Vault 擷取秘密,並將認證傳遞至連接字串。 此方法表示不需要直接在您的程式碼或環境中處理認證。 如需詳細範例,請參閱 使用受控識別來存取 Azure Key Vault 憑證。 如需 Azure Key Vault 驗證的詳細資訊,請參閱 Azure Key Vault 驗證。
如果您要直接處理代幣時的指導方針
在某些情況下,您可能會想要手動取得受管理的身分識別權杖,而不是使用內建方法來連接到目標資源。 這些情境包括:沒有您所用程式設計語言的用戶端程式庫,您要連線的目標資源,或是那些未在 Azure 上執行的資源。 手動獲取令牌時,我們會提供下列指引:
快取您取得的令牌
為了效能和可靠性,我們建議您的應用程式快取權杖到本機記憶體中,或者如果您想將其儲存至磁碟時,請將其加密。 因為受控識別權杖的有效時間為 24 小時,所以定期要求新權杖沒有任何好處,因為快取的權杖會從權杖發行端點傳回。 如果超過要求限制,您將會受到速率限制,並收到 HTTP 429 錯誤。
當您取得令牌時,可以將您的令牌快取設定為在產生令牌後將傳回 expires_on
(或等效屬性)前的 5 分鐘到期。
令牌檢查
您的應用程式不應該依賴權杖的內容。 權杖的內容僅適用於正要存取的受眾(目標資源),而不是請求該權杖的用戶端。 權杖內容可能會在未來變更或加密。
請不要公開或移動令牌
應將代幣視為認證來對待。 請不要將其公開給使用者或其他服務;例如,記錄/監視解決方案。 它們不應該從使用它們的來源資源移動,但針對目標資源進行驗證除外。
下一步