.Net Core下简单的JWT黑名单中间件
Posted 娃都会打酱油了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.Net Core下简单的JWT黑名单中间件相关的知识,希望对你有一定的参考价值。
自从JWT认证方式在互联网上蔓延后,Session认证方式就被挤掉了一大半的生存空间,这里我们不讲JWT与Session两种方式的优缺点,我们只讲如何通过JWT的黑名单来阻止某些Token的登录。
设置黑名单,也就是说要将Token
写入某个存储介质,然后考虑数据并不需要一直存在,其在有效期之后应自动释放,那这种情况下存储介质首选肯定是缓存,鉴于目前流行容器化技术,微服务概念又漫天飞的情况,缓存还得考虑支持分布式,那妥妥的必选方案就是IDistributedCache
,这样究竟是单体应用MemoryCache
,还是分布式Redis
,亦或是其它方式都可以任君选择。
选好了存储介质,那就要确定程序通过什么标志来判断确定当前是要将Token
写入黑名单,一般来说Authorization
是写在HttpHeader
里,那我们也可以考虑在HttpHeader
里增加一个Key
来标志当前请求是要注册黑名单,这里我们选用Loginout
,毕竟一般来说也就是退出登录时,才需要设置黑名单。
下面开始来具体的代码,这里是按照微软定义的Restful
规范通过StatusCode
来返回执行结果
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed;
public class JWTBlacklistMiddleware
{
private const string AuthenticationHeader = "Authorization";
private const string AuthenticationScheme = "Bearer";
private const string LoginoutHeader = "Loginout";//退出登录的Header
private const int CacheExpiration = 36000;//缓存过期时间 秒,不解析jwt数据,直接将缓存时间设置为Token的最大有效时间,以空间换性能
private readonly RequestDelegate _next;
private readonly IDistributedCache _cache;
public JWTBlacklistMiddleware(RequestDelegate next, IDistributedCache cache)
{
this._next = next;
this._cache = cache;
}
public async Task InvokeAsync(HttpContext context)
{
var auth = context.Request.Headers[AuthenticationHeader].FirstOrDefault();
if (!string.IsNullOrWhiteSpace(auth) && auth.StartsWith(AuthenticationScheme))
{
var token = auth.Substring(AuthenticationScheme.Length).Trim();
var tokenMd5 = MD5Helper.HashOf(token);//通过摘要方式降低存储空间,如果担心碰撞问题导致不应该过期的Token也过期了,可以将整个Token作为Key的一部分,Redis的Key支持512M
var cacheKey = $"TokenBLK:{tokenMd5}";
if (context.Request.Headers[LoginoutHeader].FirstOrDefault() != null)//只要带了LoginoutHeader并且value不为null,就认为是要记录黑名单
{
//将Token的摘要写入黑名单
await this._cache.SetStringAsync(cacheKey, "1", new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(CacheExpiration)
});
context.Response.StatusCode = 200;
return;
}
else if ((await this._cache.GetStringAsync(cacheKey)) != null)
{//如果是黑名单,直接返回401
context.Response.StatusCode = 401;
return;
}
}
await this._next(context);
}
}
上面代码中的MD5Helper
具体源码可见此处。
使用时也只需要在Startup
中UseMiddleware
,然后需注意下Use
的位置,一般来说应该在UseStaticFiles
之后,在UseAuthentication
之前
public void Configure(IApplicationBuilder app, IHostEnvironment env)
{
app.UseMiddleware<JWTBlacklistMiddleware>();
}
以上是关于.Net Core下简单的JWT黑名单中间件的主要内容,如果未能解决你的问题,请参考以下文章
.Net Core JWT 身份验证与自定义 API 密钥中间件
如何使用.Net Core cookie中间件ticketdataformat将Jwt令牌从Api保存到c#中的cookie