.NET CORE单用户登录
以JWT认证为例,核心思路是将用户最后一次登录的jwt信息缓存起来,每一次收到请求,都将当前jwt和缓存的jwt进行对比,如果对比结果不一致,则代表当前用户在别处登录了。
新建过滤器
/// <summary>
/// 单用户登录过滤器
/// </summary>
public class JwtAuthorizeFilter : IAuthorizationFilter
{
private readonly IMemoryCache _memoryCache;
public JwtAuthorizeFilter(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
try
{
if (context.Filters.Contains(new NoAuthenticationAttribute()) || context.Filters.Any(item => item is IAllowAnonymousFilter)) //拥有指定过滤器或者AllowAnonymous特性的请求不处理
{
return;
}
var token = context.HttpContext.Request.Headers["Authorization"].FirstOrDefault();
if (string.IsNullOrWhiteSpace(token))
{
context.Result = new JsonResult(new ApiResultContent(false) { message = ApiResultStateCode.invalid_credentials });
return;
}
var jwt = token.Split(" ")[1];
var tokenObj = new JwtSecurityToken(jwt);
var claimsIdentity = new ClaimsIdentity(tokenObj.Claims);
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
var userid = claimsPrincipal?.Claims.FirstOrDefault(c => c.Type == "id")?.Value; //登录时存入claims的用户唯一标识
var mJwt = _memoryCache.Get<string>("user" + userid);
if (mJwt != jwt)
{
context.Result = new UnauthorizedObjectResult("当前用户在别处登录");
return;
}
}
catch (Exception ex)
{
context.Result = new UnauthorizedObjectResult("身份认证不通过");
return;
}
}
}
在startup.cs文件处注册这个过滤器(.NET 3以下使用AddMvc)
services.AddControllers(o => { o.Filters.Add<JwtAuthorizeFilter>(); })
新建过滤器,将其以特性的方式增加到登录接口处(或者直接使用[AllowAnonymous])
/// <summary> /// 拥有此特性,不进行单用户登录的验证 /// </summary> public class NoAuthenticationAttribute: Attribute, IFilterMetadata { }

浙公网安备 33010602011771号