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

如何在ASP.NET Core中同时使用JWT Bearer与自定义认证方法

当然可以!ASP.NET Core的认证系统天生支持同时配置多种认证方案,刚好能完美匹配你「默认用JWT Bearer认证,仅少数场景用自定义认证头」的需求。下面我会一步步带你实现这个配置:

1. 配置多种认证方案

首先在Program.cs里,我们需要同时注册JWT Bearer认证和自定义认证方案。先设置默认认证为JWT,这样大部分接口不用额外配置就会自动使用JWT验证:

builder.Services.AddAuthentication(options =>
{
    // 设置默认的认证和挑战方案为JWT Bearer
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
// 注册JWT Bearer认证,这里按你常规的JWT配置来就行
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
})
// 注册自定义认证方案,这里给它起个名字比如"CustomHeaderAuth"
.AddScheme<AuthenticationSchemeOptions, CustomHeaderAuthenticationHandler>("CustomHeaderAuth", options => { });

2. 实现自定义认证处理器

接下来需要写一个自定义的认证处理器,用来解析和验证你的自定义认证头。这个处理器要继承AuthenticationHandler<AuthenticationSchemeOptions>,并实现核心的认证逻辑:

public class CustomHeaderAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    public CustomHeaderAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
        : base(options, logger, encoder, clock)
    {
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // 从请求头中获取自定义的认证字段,比如这里假设是"X-Custom-Token"
        if (!Request.Headers.TryGetValue("X-Custom-Token", out var customTokenHeader))
        {
            return AuthenticateResult.Fail("自定义认证头不存在");
        }

        var customToken = customTokenHeader.ToString();
        // 这里替换成你实际的自定义认证逻辑——比如验证token的有效性、查询用户信息等
        bool isTokenValid = ValidateCustomToken(customToken);

        if (!isTokenValid)
        {
            return AuthenticateResult.Fail("自定义认证头无效");
        }

        // 认证通过后,创建用户身份凭证
        var claims = new[] 
        { 
            new Claim(ClaimTypes.NameIdentifier, "custom-user-id"),
            new Claim(ClaimTypes.Name, "CustomUser")
        };
        var identity = new ClaimsIdentity(claims, Scheme.Name);
        var principal = new ClaimsPrincipal(identity);
        var ticket = new AuthenticationTicket(principal, Scheme.Name);

        return AuthenticateResult.Success(ticket);
    }

    // 示例:自定义token验证逻辑,你可以根据业务需求修改
    private bool ValidateCustomToken(string token)
    {
        // 这里只是简单示例,实际场景可能要查数据库、调用验证接口等
        return token == "YourValidCustomToken123";
    }
}

3. 给接口指定认证方案

  • 默认接口:直接用[Authorize]特性即可,因为我们已经把JWT设为默认方案,这些接口会自动走JWT认证。
  • 需要自定义认证的接口:在[Authorize]特性里指定我们刚才注册的自定义方案名称:
// 默认JWT认证的接口
[ApiController]
[Route("api/default")]
[Authorize]
public class DefaultController : ControllerBase
{
    [HttpGet]
    public IActionResult GetDefaultData()
    {
        return Ok("此接口仅允许JWT认证通过的用户访问");
    }
}

// 使用自定义认证头的接口
[ApiController]
[Route("api/custom")]
[Authorize(AuthenticationSchemes = "CustomHeaderAuth")]
public class CustomAuthController : ControllerBase
{
    [HttpGet]
    public IActionResult GetCustomData()
    {
        return Ok("此接口仅允许携带有效自定义认证头的请求访问");
    }
}

4. 注意中间件顺序

最后别忘了在Program.cs里按正确顺序添加中间件——认证中间件必须在授权中间件之前:

app.UseAuthentication();
app.UseAuthorization();

额外小技巧

如果某个接口需要支持两种认证方式都能访问(比如既可以用JWT,也可以用自定义头),只需要把多个方案用逗号分隔即可:

[Authorize(AuthenticationSchemes = $"{JwtBearerDefaults.AuthenticationScheme},CustomHeaderAuth")]

这样请求只要满足其中一种认证方式,就能成功访问接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:08:57