.Net核心JWT自定义过期令牌响应

时间:2019-08-16 11:23:31

标签: c# asp.net-core jwt

我已经配置了我的Web API以与JWT和一次刷新令牌一起使用。

但是,我想修改标准的JWT中间件以使用具有响应头(而不是标准的HTTP 401响应)的HTTP 200响应已过期令牌的客户端。

我已将此代码添加到services.AddAuthentication()启动配置中。

            services.AddAuthentication()
            .AddJwtBearer("Bearer", options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
                    ValidateAudience = false,
                    ValidateIssuer = false,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])),
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero //the default for this setting is 5 minutes
                };
                options.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("Token-Expired", "True");
                            context.Response.StatusCode = 200;
                        }
                        return Task.CompletedTask;
                    }
                };
            });

但是返回给客户端的响应仍然是HTTP401。那么我会丢失什么吗?

1 个答案:

答案 0 :(得分:0)

返回Task.Completed不一定结束中间件管道。它会继续运行并最终到达应用程序。UseMvc()会将状态代码设置为401。

您需要在app.UseAuthentication()管道之后但在app.UseMvc()之前短路管道。

这是中间件代码:

    public class ExpiredTokenMiddleware
    {
        private readonly RequestDelegate _next;

        public ExpiredTokenMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            if (context.Response.Headers["Token-Expired"] == "True")
            {
                context.Response.StatusCode = 200;

                // DO NOT CALL NEXT. THIS SHORTCIRCUITS THE PIPELINE
            }
            else
            {
                await _next(context);
            }
        }
    }

然后将中间件插入两者之间的startup.cs中。

        app.UseAuthentication();
        app.UseMiddleware<ExpiredTokenMiddleware>();
        app.UseMvc();