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

ASP.NET Core API对接外部身份服务的最佳认证方案咨询

自定义外部身份服务对接ASP.NET Core API的最佳认证实践

当前实现方案

你目前通过自定义顶级中间件实现认证逻辑,每个请求都会调用身份服务API验证Token,具体代码如下:

数据API的自定义认证中间件

public class CustomAuthMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;
    private readonly IAuthenticationService _authenticationService;

    public CustomAuthMiddleware(RequestDelegate next, ILoggerFactory logFactory, IAuthenticationService authenticationService)
    {
        _next = next;
        _logger = logFactory.CreateLogger<CustomAuthMiddleware>();
        _authenticationService = authenticationService;
    }

    public async Task Invoke(HttpContext context)
    {
        string token = context.Request.Headers["ApiToken"];

        if (!string.IsNullOrEmpty(token))
        {
            // 调用身份服务API验证Token
            var isVerified = await _authenticationService.VerifyToken(token);

            if (isVerified)
                await _next(context);
        }

        throw new AppException(System.Net.HttpStatusCode.NotFound);
    }
}

身份服务的Token验证接口

[Authorize]
[HttpGet("verifyToken")]
public async Task<IActionResult> verifyToken()
{
    var user = await _userManager.FindByEmailAsync(User.FindFirstValue(ClaimTypes.Email));

    if (user != null)
        return Ok();

    return BadRequest();
}

该方案可正常运行,但存在性能损耗(每次请求都需调用身份服务)、未集成ASP.NET Core原生认证体系的问题,以下是更符合最佳实践的优化方案:

推荐的优化方案

1. JWT本地验证(无中心化调用,性能最优)

如果身份服务颁发的是JWT令牌,可直接在数据API本地完成验证,无需每次请求身份服务:

  • 身份服务采用非对称加密算法(如RS256)生成JWT,将公钥提供给数据API,私钥由身份服务保管
  • 数据API配置JWT认证中间件,用公钥验证令牌的签名、过期时间、受众等信息
  • 验证通过后,令牌中的Claims会自动填充到HttpContext.User,可直接用[Authorize]属性控制接口访问

配置示例:

// Program.cs中配置认证服务
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = "你的身份服务域名",
            ValidateAudience = true,
            ValidAudience = "数据API的受众标识",
            ValidateLifetime = true,
            IssuerSigningKey = new JsonWebKey("身份服务公开的公钥"),
            ValidateIssuerSigningKey = true
        };
    });

// 启用认证、授权中间件(注意顺序:先认证后授权)
app.UseAuthentication();
app.UseAuthorization();

之后只需在需要认证的接口上添加[Authorize]属性即可,无需自定义中间件。

2. OAuth 2.0 Token Introspection(中心化验证,符合标准协议)

如果需要支持令牌提前吊销等场景,必须保持中心化验证,可使用OAuth 2.0的Token Introspection规范(RFC 7662):

  • 身份服务实现标准的Introspection端点,数据API向该端点发送Token获取验证结果
  • 使用IdentityModel.AspNetCore库集成Introspection中间件,替代自定义中间件,自带缓存机制可减少身份服务压力

配置示例:

// Program.cs中配置认证服务
builder.Services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme)
    .AddOAuth2Introspection(options =>
    {
        options.Authority = "你的身份服务域名";
        options.ClientId = "数据API的客户端ID";
        options.ClientSecret = "数据API的客户端密钥";
        // 配置验证结果缓存时长,避免重复调用
        options.CacheDuration = TimeSpan.FromMinutes(5);
    });

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

现有方案的最小改进(若需保留自定义逻辑)

如果因特殊原因必须保留自定义验证逻辑,建议:

  • 认证失败时返回401 Unauthorized而非404 NotFound,设置context.Response.StatusCode = StatusCodes.Status401Unauthorized并返回标准错误响应
  • 添加Token验证结果缓存,短期缓存已验证的Token,减少重复调用身份服务
  • 实现IAuthenticationHandler集成到ASP.NET Core认证体系,而非使用顶级自定义中间件,这样可配合[Authorize]属性使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:20:31