我已经配置了我的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。那么我会丢失什么吗?
答案 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();