客户端凭证流获取令牌后调用ASP.NET Core API提示未授权的原因排查
我有一个基于Angular(MSAL)+ ASP.NET Core Web API的Azure AD集成环境,当前UI可以正常调用API。但现有后端进程需要调用同一ASP.NET Core 6 Web API,我编写的方法已经成功获取到令牌,但提交给API时却提示未授权。我已经修改了目标作用域,问题仍然存在,请问可能的原因是什么?
附获取令牌的代码:
public AccessTokenModel GetAccessTokenModelSameClient() { string url = $"https://login.microsoftonline.com/{mytenantID}/oauth2/v2.0/token"; var clientId = "{API_CLIENT_ID}"; string grant_type = "client_credentials"; string clientSecret = "mysecret"; string scope = $"api://{Client_ID_For_API}/.default"; var body = $"grant_type={grant_type}&client_id={clientId}&client_secret={clientSecret}&scope={scope}"; using (var httpClient = new HttpClient()) { var stringContent = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded"); var result = httpClient.PostAsync(url, stringContent).Result; if (result.IsSuccessStatusCode) { var json = result.Content.ReadAsStringAsync().Result; return JsonConvert.DeserializeObject<AccessTokenModel>(json); } else { var error = result.Content.ReadAsStringAsync().Result; throw new ApplicationException(error); } } }
API应用权限未正确配置
Client Credentials流属于应用级权限,而非用户委托权限。你需要在Azure AD中找到获取令牌的后端应用,为其添加目标API的应用权限(注意选“应用权限”而非“委托权限”),并且必须由租户管理员完成同意授权。检查权限列表中是否存在api://{API_CLIENT_ID}/.default对应的权限,且状态为“已授予管理员同意”。令牌受众(aud)不匹配
用JWT解析工具打开你获取到的令牌,查看aud字段是否严格等于目标API的客户端ID(格式为api://{API_CLIENT_ID})。如果aud字段值错误,API会直接拒绝请求。确认代码中Client_ID_For_API变量确实是目标API的客户端ID,没有拼写错误。API身份验证配置错误
检查ASP.NET Core 6 API的Program.cs中的AAD配置:builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));对应的
appsettings.json中AzureAd节点的ClientId必须是API自身的客户端ID,TenantId要与获取令牌时使用的租户ID一致。另外,若开启了ValidateAudience验证,必须保证令牌的aud与API配置的ClientId完全匹配。令牌版本与API配置不兼容
解析令牌查看iss字段:v1版本令牌的iss为https://sts.windows.net/{tenantId}/,v2版本为https://login.microsoftonline.com/{tenantId}/v2.0。确保API配置的Authority与令牌的iss一致,否则API无法验证令牌的合法性。客户端ID/密钥混淆错误
代码中的clientId是后端应用自身的客户端ID,而非目标API的客户端ID;clientSecret是后端应用在Azure AD中生成的客户端密钥。如果此处混淆了API和后端应用的ID,即便能拿到令牌,API也不会认可该应用的权限。
内容的提问来源于stack exchange,提问作者Tom Kurian

