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

.NET Core 7 Web API如何同时实现JWT与Azure AD令牌授权?

.NET Core 7 Web API集成JWT与Azure AD令牌授权解决Scheme冲突问题

问题描述

在.NET Core 7 Web API中同时实现JWT令牌与Azure AD令牌授权时,单独使用两种授权方式均正常,但组合后出现scheme already exists bearer错误。原有实现代码如下:

Azure AD实现代码

builder.Services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")).EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

JWT令牌实现代码

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
               .AddJwtBearer(jwtBearerOptions =>
               { 
                   jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters()
                   {
                       ValidateAudience = true,
                       ValidateLifetime = true,
                       ValidateIssuerSigningKey = true,
                       ValidIssuer = tokenOptions.Issuer,
                       ValidAudience = tokenOptions.Audience,
                       IssuerSigningKey = signingConfigurations.Key,
                       ClockSkew = TimeSpan.Zero
                   }; 
               });

解决方案

错误根源在于Azure AD和JWT默认均使用Bearer作为认证Scheme名称,导致注册时命名冲突。只需为两者指定不同的Scheme名称,再通过策略或直接在接口上指定即可实现共存。

1. 为两种认证方式分配独特Scheme名称

修改注册代码,给Azure AD和JWT分别指定自定义Scheme名称,避免冲突:

// 注册Azure AD认证,使用自定义Scheme名称"AzureAdBearer"
builder.Services.AddAuthentication()
    .AddMicrosoftIdentityWebApi("AzureAdBearer", builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

// 注册JWT认证,使用自定义Scheme名称"JwtBearer"
builder.Services.AddJwtBearer("JwtBearer", jwtBearerOptions =>
{ 
    jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = tokenOptions.Issuer,
        ValidAudience = tokenOptions.Audience,
        IssuerSigningKey = signingConfigurations.Key,
        ClockSkew = TimeSpan.Zero
    }; 
});

2. 配置全局默认认证策略(可选)

若希望API全局支持两种认证方式的自动识别验证,可添加一个PolicyScheme作为默认认证方案,根据令牌特征自动选择对应的Scheme:

// 设置默认认证方案为自定义的多认证策略
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "MultiAuthScheme";
    options.DefaultChallengeScheme = "MultiAuthScheme";
})
// 注册PolicyScheme,协调两种认证方式
.AddPolicyScheme("MultiAuthScheme", "MultiAuthScheme", options =>
{
    options.ForwardDefaultSelector = context =>
    {
        var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
        if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("Bearer "))
        {
            var token = authHeader.Substring("Bearer ".Length).Trim();
            var tokenHandler = new JwtSecurityTokenHandler();
            if (tokenHandler.CanReadToken(token))
            {
                var jwtToken = tokenHandler.ReadJwtToken(token);
                // 根据令牌的issuer判断是否为Azure AD颁发的令牌
                if (jwtToken.Issuer.Contains("login.microsoftonline.com"))
                {
                    return "AzureAdBearer";
                }
            }
        }
        // 默认使用JWT认证Scheme
        return "JwtBearer";
    };
});

3. 接口级别指定认证方案(可选)

如果不需要全局默认,也可以在单个控制器或接口上明确允许两种认证Scheme:

[Authorize(AuthenticationSchemes = "AzureAdBearer,JwtBearer")]
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    // 接口业务逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:22:04