You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 2.0 Web API Azure AD JWT签名无效及令牌适配问题

问题拆解与解决方案

看起来你在Azure AD令牌版本混用和On-Behalf-Of(OBO)流程上踩了好几个典型的坑,我来帮你逐一理清问题根源:

1. 为什么ADAL的V1令牌能过Graph,但Web API返回"Invalid Signature"?

这个问题的核心是V1令牌的发行者格式和你Web API配置的Authority不匹配。ASP.NET Core 2.0的JWT中间件默认会严格验证Issuer,而Azure AD V1令牌的Issuer是https://sts.windows.net/TENANT_ID/(注意末尾的斜杠),但你配置的Authority是https://login.microsoftonline.com/TENANT_ID,两者格式不一致,导致签名验证失败。

解决办法是调整Web API的JWT验证参数,明确指定V1令牌的ValidIssuer:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://login.microsoftonline.com/TENANT_ID";
        options.Audience = "CLIENT_ID";
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = "https://sts.windows.net/TENANT_ID/", // 匹配V1令牌的发行者格式
            ValidateAudience = true,
            ValidAudience = "CLIENT_ID",
            ValidateIssuerSigningKey = true
        };
    });

2. 为什么MSAL的V2令牌能过Web API,但调用Graph失败?

这是因为令牌的受众(Audience)不对。你用MSAL获取的V2令牌,受众是Web API的CLIENT_ID,而不是Microsoft Graph的资源ID。Graph不会接受受众不是自己的令牌,自然会返回失败。

正确的做法是:不要让SPA直接拿Graph令牌给Web API,而是让Web API通过OBO流程,用SPA传来的用户令牌去申请Graph的访问令牌——这才是后端API调用Graph的标准方式。

3. 为什么用V2令牌做用户断言时,AcquireTokenAsync抛出版本不匹配错误?

这个问题通常有两个原因:

  • 你用了V1的OBO端点来处理V2令牌:V2令牌必须对应V2的令牌端点https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token,如果你的MSAL配置还是指向V1的Authority,就会触发这个错误。
  • Scope格式不正确:V2流程中请求Graph权限时,必须用完整的Scope格式(比如https://graph.microsoft.com/User.Read),而不是V1的短格式。

解决办法是确保你的MSAL客户端配置用V2的Authority,并且请求正确的Graph Scope:

// 初始化MSAL机密客户端,指定V2端点
var confidentialClient = ConfidentialClientApplicationBuilder
    .Create("WEB_API_CLIENT_ID")
    .WithClientSecret("WEB_API_CLIENT_SECRET")
    .WithAuthority(new Uri("https://login.microsoftonline.com/TENANT_ID/v2.0"))
    .Build();

// 用用户的V2令牌做断言,申请Graph令牌
var result = await confidentialClient.AcquireTokenOnBehalfOf(
    new[] { "https://graph.microsoft.com/User.Read" }, // 完整的Graph Scope
    new UserAssertion(userJwtTokenFromSPA))
    .ExecuteAsync();

总结建议:统一用V2流程

为了避免版本混用的麻烦,建议你全链路切换到V2:

  1. 确保SPA和Web API都在Azure AD的V2端点注册(或开启V2令牌支持);
  2. SPA用MSAL获取Web API的令牌,请求的Scope是你为Web API定义的自定义Scope(比如api://WEB_API_CLIENT_ID/access_as_user);
  3. Web API的JWT验证配置用V2的Authority和Issuer;
  4. Web API通过MSAL的OBO流程,用用户令牌申请Graph的V2令牌。

另外,你可以用jwt.ms解码令牌,检查Issuer、Audience、Scopes等字段是否符合预期,这是快速排查令牌问题的好工具。

内容的提问来源于stack exchange,提问作者Abraxas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:21:06