如何在Azure VM上使用托管身份通过MSAL调用Azure Web App API
解决方案:用Azure托管身份替代客户端密钥访问API
第一步:配置VM的托管身份
- 给Azure VM启用系统分配或用户分配的托管身份(优先推荐用户分配,方便跨资源复用)
- 将该托管身份授予
ApiAppReg的应用角色权限:在Azure门户进入ApiAppReg应用注册→应用角色→分配用户/组/服务主体,选择VM的托管身份(服务主体类型)并分配对应权限
第二步:修改代码,用托管身份获取令牌
你可以选择两种方式实现,都是无需存储客户端密钥的方案:
方式一:用DefaultAzureCredential直接获取令牌(符合你已有的使用习惯)
不需要依赖MSAL,直接借助Azure.Identity库的凭据类获取令牌:
using Azure.Identity; using Azure.Core; // 目标API的作用域格式:api://{ApiAppReg的客户端ID}/.default string apiScope = "api://{ApiAppReg-Client-Id}/.default"; string tenantId = "{Tenant-Id}"; // 若使用用户分配的托管身份,需指定ManagedIdentityClientId var credential = new DefaultAzureCredential(); var tokenRequestContext = new TokenRequestContext(new[] { apiScope }) { TenantId = tenantId }; AccessToken accessToken = await credential.GetTokenAsync(tokenRequestContext); string token = accessToken.Token;
补充:如果是用户分配的托管身份,初始化凭据时需指定ID:
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = "{用户分配托管身份的ClientId}" });
方式二:在MSAL中集成托管身份(保留MSAL SDK的使用)
MSAL.NET支持将托管身份作为机密客户端的凭据,修改原有代码如下:
using Microsoft.Identity.Client; using Azure.Identity; string managedIdentityClientId = "{用户分配托管身份的ClientId}"; // 或系统分配身份可留空,用VM的标识 string tenantId = "{Tenant-Id}"; string apiScope = "api://{ApiAppReg-Client-Id}/.default"; var managedIdentityCredential = new ManagedIdentityCredential(managedIdentityClientId); var msalClientApp = ConfidentialClientApplicationBuilder .Create(managedIdentityClientId) .WithAuthority(AzureCloudInstance.AzurePublic, tenantId) .WithManagedIdentity(managedIdentityCredential) .Build(); AuthenticationResult authResult = await msalClientApp .AcquireTokenForClient(new[] { apiScope }) .ExecuteAsync(); string accessToken = authResult.AccessToken;
关键注意事项
- 必须确保VM的托管身份已获得
ApiAppReg的应用角色权限,否则会出现权限不足的错误 - 客户端凭据流要求作用域必须使用
api://{ApiAppReg-Client-Id}/.default格式,不能用动态作用域 - 两种方案都不需要存储任何密钥,凭据类会自动从VM的托管身份元数据服务获取令牌
内容的提问来源于stack exchange,提问作者Stanton
相关产品推荐
相关产品推荐

