MVC应用调用独立WebAPI时Azure AD令牌授权失败问题
解决方案建议:MVC应用调用Azure AD保护的独立WebAPI
我之前踩过几乎一模一样的坑,OIDC生成的token没法访问独立API的核心原因是:MVC默认拿到的是用于身份验证的id_token,而WebAPI需要的是针对自身资源的access_token。下面是几个亲测有效的解决步骤:
1. 配置OIDC时明确请求API的Access Token
在MVC应用的Startup.cs中,修改OpenID Connect配置,指定API的专属资源范围,并确保请求返回access_token:
services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie() .AddOpenIdConnect(options => { options.ClientId = "你的MVC应用ClientID"; options.TenantId = "你的租户ID"; options.Authority = "https://login.microsoftonline.com/你的租户ID/v2.0"; // 关键:添加API的专属scope,格式为api://<API ClientID>/<权限名称> options.Scope.Add("api://你的WebAPI ClientID/access_as_user"); options.Scope.Add("offline_access"); // 可选,用于自动刷新token // 要求返回授权码+id_token+access_token options.ResponseType = "code id_token"; // 把token保存到Cookie,方便后续调用API时获取 options.SaveTokens = true; });
注意:要确保Azure AD中已经给MVC应用授予了该API scope的权限(管理员或用户同意均可)。
2. 调用API时使用正确的Access Token
在MVC的Controller中,从HttpContext获取针对API的access_token,而非id_token:
public async Task<IActionResult> CallProtectedApi() { // 从Cookie中获取access_token var accessToken = await HttpContext.GetTokenAsync("access_token"); if (string.IsNullOrEmpty(accessToken)) { // 没有token时,触发登录流程获取 return Challenge(OpenIdConnectDefaults.AuthenticationScheme); } // 调用API时携带Bearer token var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); var response = await httpClient.GetAsync("你的WebAPI独立URL"); if (response.IsSuccessStatusCode) { var apiResponse = await response.Content.ReadAsStringAsync(); return Ok(apiResponse); } else { // 处理授权失败的情况,比如401 return StatusCode((int)response.StatusCode, "API访问被拒绝"); } }
3. 验证WebAPI的Azure AD配置
确保WebAPI的Startup.cs中配置的受众(Audience)是自身的ClientID,而非MVC应用的:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Audience = "你的WebAPI ClientID"; // 必须是API自己的ClientID options.Authority = "https://login.microsoftonline.com/你的租户ID/v2.0"; });
4. 排查Token有效性
可以用jwt.ms解析拿到的access_token,重点检查两个字段:
- aud:必须等于WebAPI的ClientID,若显示MVC应用的ClientID,说明请求时未指定正确的API scope
- scp:必须包含你配置的API权限(比如
access_as_user)
内容的提问来源于stack exchange,提问作者SVG
相关产品推荐
相关产品推荐

