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

.NET Core 2.2中如何验证Azure AD颁发的JWT Bearer Token?

解决.NET Core 2.2中Azure AD JWT验证返回401的问题

我碰到过好几个类似的情况,大多是身份验证中间件的配置细节没对齐Azure AD的要求,导致带[Authorize]特性的接口返回401。下面给你一步步的配置方案和排查要点:

1. 先安装必要的NuGet包

在你的.NET Core 2.2项目中,需要安装Microsoft.AspNetCore.Authentication.JwtBearer包,它提供了JWT令牌验证的核心功能。你可以通过NuGet包管理器或者命令行安装:

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 2.2.0

2. 配置Startup.cs的ConfigureServices方法

在ConfigureServices中添加身份验证服务,并针对Azure AD的JWT进行配置,关键是要对齐Azure AD的租户ID、客户端ID(受众)以及令牌签发者信息:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;

public void ConfigureServices(IServiceCollection services)
{
    // 替换为你的Azure AD租户ID和应用客户端ID
    var tenantId = "你的Azure AD租户ID";
    var clientId = "你的应用注册客户端ID";

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            // 设置Azure AD的授权端点
            options.Authority = $"https://login.microsoftonline.com/{tenantId}/v2.0";
            // 设置令牌的受众(必须和Azure AD中注册的应用ID一致)
            options.Audience = clientId;

            // 配置令牌验证参数
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                // 签发者地址要和Azure AD返回的令牌中的iss字段匹配
                ValidIssuer = $"https://login.microsoftonline.com/{tenantId}/v2.0",
                ValidateAudience = true,
                ValidAudience = clientId,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                // 自动从Azure AD的元数据获取签名密钥,避免手动配置密钥过期问题
                IssuerSigningKeyResolver = (token, securityToken, kid, parameters) =>
                {
                    var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(
                        $"{options.Authority}/.well-known/openid-configuration",
                        new OpenIdConnectConfigurationRetriever());
                    var openIdConfig = configManager.GetConfigurationAsync().GetAwaiter().GetResult();
                    return openIdConfig.SigningKeys.Where(k => k.KeyId == kid);
                }
            };

            // 添加事件监听,方便排查验证失败的原因
            options.Events = new JwtBearerEvents
            {
                OnAuthenticationFailed = context =>
                {
                    // 这里可以记录日志,或者输出错误信息帮助排查
                    Console.WriteLine($"令牌验证失败: {context.Exception.Message}");
                    return Task.CompletedTask;
                }
            };
        });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

3. 确保在Configure方法中启用身份验证

一定要在UseMvc之前调用UseAuthentication,否则身份验证中间件不会生效:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    // 必须在UseMvc之前启用身份验证
    app.UseAuthentication();

    app.UseHttpsRedirection();
    app.UseMvc();
}

4. 常见排查要点

如果配置后还是返回401,你可以从这几个方面检查:

  • 令牌格式是否正确:前端请求头中的Authorization必须是Bearer {你的JWT令牌}格式,不要漏掉Bearer前缀
  • 受众(aud)是否匹配:用在线工具解码令牌,确认aud字段的值和你配置的clientId完全一致
  • 签发者(iss)是否匹配:Azure AD的v1.0和v2.0端点返回的iss格式不同,v1是https://sts.windows.net/{tenantId}/,v2是https://login.microsoftonline.com/{tenantId}/v2.0,要确保配置的ValidIssuer和令牌中的iss一致
  • API权限是否配置正确:在Azure AD的应用注册中,确认你已经添加了对应的API权限,并且授予了管理员同意(如果需要)
  • 令牌是否过期:解码令牌查看exp字段,确认令牌还在有效期内

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:56:47