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

ASP.NET Core 2.2中AuthenticationFailedContext.Success()调用无效求助

问题分析与解决方案

你遇到的问题核心是:在OnAuthenticationFailed事件中完成refresh token验证并签发新令牌后,尽管调用了context.Success(),但认证中间件仍然返回403并终止请求管道——这是因为**OnAuthenticationFailed触发时,认证流程已经标记为失败,默认会生成错误响应结果,单纯调用Success()无法覆盖这个预设结果**。

解决方案:重置认证结果,让请求继续流转

在你成功验证refresh token并完成新令牌签发的代码分支中,除了设置context.Principal和调用context.Success(),还需要手动清除context.Result(它默认被赋值为错误响应),告诉认证中间件不要返回错误,而是继续将请求传递到后续的控制器逻辑。

修改你的AuthenticationFailed方法:

public static async Task AuthenticationFailed(this AuthenticationFailedContext context)
{
    ILoggerFactory loggerFactory = context.HttpContext.RequestServices.GetService<ILoggerFactory>();
    ILogger logger = loggerFactory.CreateLogger(nameof(JwtBearerExtensions));
    string refreshToken = context.HttpContext.Request.Cookies[Defaults.RefreshTokenCookie];
    if (string.IsNullOrEmpty(refreshToken))
    {
        logger.LogWarning("No refresh token supplied with invalid JWT, Cookies are {0}", string.Join(", ", context.HttpContext.Request.Cookies.Keys));
        return;
    }
    logger.LogInformation("Processing refresh token '{0}'.", refreshToken);
    IConfiguration configuration = context.HttpContext.RequestServices.GetService<IConfiguration>();
    IUserService userService = context.HttpContext.RequestServices.GetService<IUserService>();
    ITokenHandler handler = context.HttpContext.RequestServices.GetService<ITokenHandler>();
    long? userId = await handler.ValidateRefreshToken(refreshToken);
    if (userId.HasValue)
    {
        User user = await userService.GetUserAsync(userId.Value);
        refreshToken = await handler.GenerateRefreshToken(userId.Value);
        string jwtToken = BuildJwtToken(user, configuration);
        context.HttpContext.Response.AddBearerAuthorization(jwtToken);
        context.HttpContext.Response.AddRefreshTokenCookie(refreshToken);
        context.Principal = new ClaimsPrincipal(BuildClaimsIdentity(user));
        context.Success();
        
        // 关键:清除错误结果,让请求继续向下流转
        context.Result = new NoResult();
    }
}

为什么这样有效?

当JWT验证失败触发OnAuthenticationFailed时,JwtBearer中间件会默认将context.Result设置为一个错误响应(比如UnauthorizedResult),即使你调用context.Success()标记认证成功,中间件仍然会优先返回这个预设的错误结果。通过将context.Result设置为NoResult(),你告诉中间件“不需要返回任何响应,继续处理请求”,这样请求就会被传递到你的控制器方法,同时新的令牌和refresh token已经被添加到响应头和Cookie中。

额外注意事项

  • 确保你的BuildClaimsIdentity方法生成的ClaimsIdentity是有效的,并且包含后续授权所需的所有声明。
  • 验证AddBearerAuthorization和AddRefreshTokenCookie扩展方法是否正确设置了响应头和Cookie(比如Cookie的过期时间、SameSite属性等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:58:25