本地Visual Studio 2022环境下通过用户分配托管身份获取Azure AD保护API访问令牌失败求助
大家好,我现在遇到一个Azure托管身份令牌获取的问题,想请各位帮忙看看:
我在Azure AD层面配置了一个用户分配的托管身份,同时有一个受Azure AD保护的REST API,这个API定义了名为CustomRole的应用角色,并且已经给托管身份分配了Application类型的CustomRole权限。
我用ASP.NET Core 3.1写了如下代码来获取访问令牌:
public async Task<string> GetL10AccessTokenAsync() { var token = await GetTokenUsingManagedIdentityAsync("<ClientId of the REST API>").ConfigureAwait(false); var accessToken = token.Token; return accessToken; } public async Task<AccessToken> GetTokenUsingManagedIdentityAsync(string azureServiceKey) { var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = ConfigManager.Get(UserAssignedClientId), ExcludeEnvironmentCredential = true, ExcludeInteractiveBrowserCredential = true, ExcludeAzurePowerShellCredential = true, ExcludeSharedTokenCacheCredential = true, ExcludeVisualStudioCodeCredential = true, ExcludeVisualStudioCredential = false, ExcludeAzureCliCredential = true, ExcludeManagedIdentityCredential = false }); var tokenRequestContext = new TokenRequestContext(new[] { ConfigManager.Get(azureServiceKey) }); return await credential.GetTokenAsync(tokenRequestContext, default).ConfigureAwait(false); }
当我在本地用Visual Studio 2022(企业版)运行这段代码时,收到了如下错误:
{ "ErrorCode": 500, "Message": "DefaultAzureCredential failed to retrieve a token from the included credentials. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/defaultazurecredential/troubleshoot\r\n- WorkloadIdentityCredential authentication unavailable. The workload options are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/workloadidentitycredential/troubleshoot\r\n- ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.\r\n- Process \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\IDE\\CommonExtensions\\Microsoft\\Asal\\TokenService\\Microsoft.Asal.TokenService.exe\" has failed with unexpected error: TS003: Error, TS004: Unable to get access token. 'WAM Error \r\n Error Code: 3399614476 \r\n Error Message: SubError: consent_required V2Error: invalid_grant AADSTS65001: The user or administrator has not consented to use the application with ID '04f0c124-f2bc-4f59-8241-bf6df9866bbd' named 'Visual Studio'. Send an interactive authorization request for this user and resource. Trace ID: 54bf2c95-47c4-46d6-a5e7-7fbe54812600 Correlation ID: 187a7568-4146-4ec2-a605-a808af9450a1 Timestamp: 2024-02-20 10:32:19Z \r\n Internal Error Code: 557973645 \r\n'.\r\n- Azure Developer CLI could not be found.", "Type": "CredentialUnavailableException", "StackTrace": " at Azure.Identity.DefaultAzureCredential.GetTokenFromSourcesAsync(TokenCredential[] sources, TokenRequestContext requestContext, Boolean async, CancellationToken cancellationToken)\r\n at Azure.Identity.DefaultAzureCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)\r\n at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex, String additionalMessage, Boolean isCredentialUnavailable)\r\n at Azure.Identity.DefaultAzureCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)\r\n at Azure.Identity.DefaultAzureCredential.GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)\r\n", "InnerException": "Multiple exceptions were encountered while attempting to authenticate. (WorkloadIdentityCredential authentication unavailable. The workload options are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/workloadidentitycredential/troubleshoot) (ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.) (Process \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\IDE\\CommonExtensions\\Microsoft\\Asal\\TokenService\\Microsoft.Asal.TokenService.exe\" has failed with unexpected error: TS003: Error, TS004: Unable to get access token. 'WAM Error \r\n Error Code: 3399614476 \r\n Error Message: SubError: consent_required V2Error: invalid_grant AADSTS65001: The user or administrator has not consented to use the application with ID '04f0c124-f2bc-4f59-8241-bf6df9866bbd' named 'Visual Studio'. Send an interactive authorization request for this user and resource. Trace ID: xxxx-xxxx-xxxx-xxxx-xxxxxx Correlation ID: xxxxx-xxxxx-xxxx-xxxx-xxxxxxx Timestamp: xxxx-xx-xx yy:yy:yyy \r\n Internal Error Code: 557973645 \r\n'.) (Azure Developer CLI could not be found.)" }
错误里核心的问题是AADSTS65001,提示Visual Studio的应用没有被授权访问目标资源,想请教各位有没有解决这个问题的办法?
我来分享几个实用的解决思路,你可以逐一尝试:
1. 先理清错误根源
你看到的AADSTS65001错误,本质是因为代码里ExcludeVisualStudioCredential设为false,导致DefaultAzureCredential尝试用Visual Studio登录的用户身份请求令牌,但Visual Studio对应的Azure AD公共应用(ID:04f0c124-f2bc-4f59-8241-bf6df9866bbd)并没有被授予访问目标API的CustomRole权限,也没有完成管理员同意,所以被AAD拒绝。
另外要注意:本地环境本身无法直接调用Azure托管身份的端点(托管身份是Azure资源专属身份,仅在Azure内部环境生效),所以代码里的ManagedIdentityCredential失败是正常现象。
2. 调整Credential配置,规避Visual Studio身份尝试
既然目标是用托管身份,本地调试时可以先排除Visual Studio的Credential,避免触发无效请求。修改你的DefaultAzureCredentialOptions配置:
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = ConfigManager.Get(UserAssignedClientId), ExcludeEnvironmentCredential = true, ExcludeInteractiveBrowserCredential = true, ExcludeAzurePowerShellCredential = true, ExcludeSharedTokenCacheCredential = true, ExcludeVisualStudioCodeCredential = true, ExcludeVisualStudioCredential = true, // 改为true,排除VS身份 ExcludeAzureCliCredential = false, // 改为false,用Azure CLI做本地调试身份 ExcludeManagedIdentityCredential = false });
3. 本地调试的替代方案:用Azure CLI模拟身份
修改配置后,需要在本地通过Azure CLI获取有效身份:
- 打开命令行工具,运行
az login,用拥有目标API访问权限的Azure账号登录(或给该账号分配CustomRole权限) - 登录成功后再运行代码,
DefaultAzureCredential会自动使用Azure CLI的身份获取令牌
如果想更贴近生产环境的托管身份逻辑(应用身份而非用户身份),可以:
- 创建一个测试用的服务主体,给它分配
CustomRole的Application权限并完成管理员同意 - 用命令
az login --service-principal -u <服务主体ClientId> -p <密钥> --tenant <租户Id>登录Azure CLI - 再运行代码,这样就和生产环境的托管身份流程完全一致了
4. 临时方案:给Visual Studio应用授权(不推荐)
如果一定要用VisualStudioCredential调试,可以让Azure AD管理员给Visual Studio的公共应用(ID:04f0c124-f2bc-4f59-8241-bf6df9866bbd)分配CustomRole的Application权限,并完成管理员同意。不过这个应用是微软公共应用,授权后存在安全风险,仅建议在测试环境临时使用。
备注:内容来源于stack exchange,提问作者santosh kumar patro

