using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.Login;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Services.Public;
namespace WMS.Web.Repositories.DependencyInjection
{
///
/// token 黑名单中间件
///
public class AuthorizationTokenSecurityPolicy
{
private readonly RequestDelegate _next;
private readonly IMemoryCache _cache;
private ILogger _logger;
private DateTime _refreshTime = DateTime.Now.AddYears(-5);
private readonly RedisClientService _redisClientService;
///
/// token黑名单中间件
///
///
///
public AuthorizationTokenSecurityPolicy(RequestDelegate next, ILogger logger, IMemoryCache cache, RedisClientService redisClientService)
{
_next = next;
_cache = cache;
this._logger = logger;
_redisClientService = redisClientService;
}
///
/// 事件
///
///
///
public async Task Invoke(HttpContext context, ILoginService loginService)
{
string authorization = context.Request.Headers["Authorization"];
string path = context.Request.Path.Value.ToLower();
string[] pathlist = path.Split('/');
bool isLogin = pathlist.Where(x => x == "login" || x.ToLower() == "heart" || x.ToLower() == "test").Any();
if (isLogin)
{
context.Response.StatusCode = 200;
await _next(context);
return;
}
if (string.IsNullOrEmpty(authorization))
{
context.Response.StatusCode = 401;
var result = JsonConvert.SerializeObject(new { status = 401, data = string.Empty, message = "授权失败,请重新登录" });
context.Response.ContentType = "application/json;charset=utf-8";
await context.Response.WriteAsync(result);
return;
}
else
{
string token = string.Empty;
if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
{
token = authorization.Substring("Bearer ".Length).Trim();
}
//判断前端过来的token
if (string.IsNullOrEmpty(token))
{
context.Response.StatusCode = 401;
var result = JsonConvert.SerializeObject(new { status = 401, data = string.Empty, message = "授权失败,请重新登录" });
context.Response.ContentType = "application/json;charset=utf-8";
await context.Response.WriteAsync(result);
return;
}
//1.验证是否有登录数据缓存
var logininfo = _redisClientService.GetStringKey($"wms_login_{token}");
if (logininfo == null)
{
context.Response.StatusCode = 401;
var result = JsonConvert.SerializeObject(new { status = 401, data = string.Empty, message = "授权失败,请重新登录" });
context.Response.ContentType = "application/json;charset=utf-8";
await context.Response.WriteAsync(result);
return;
}
else
{
_logger.LogInformation("RefreshToken:我在刷新登录--1"+ logininfo.TokenInfo.Expired.ToString());
//2.判断缓存的token 过期时间
if (!string.IsNullOrEmpty(logininfo.TokenInfo.Token) && logininfo.TokenInfo.Expired.AddMinutes(-10) <= DateTime.Now)
{
_logger.LogInformation("RefreshToken:我在刷新登录--2");
var refreshtokeninfo = RefreshToken(logininfo.TokenInfo.Token, logininfo.TokenInfo.RefreshToken, loginService);
var info = _redisClientService.GetStringKey($"wms_login_{token}");
_logger.LogInformation("RefreshToken:我在刷新登录--完成:" + info.UserInfo.Nickname);
//刷新token后不能删除_redis用户缓存
//if (!refreshtokeninfo)
//{
// RemoveRedisLoginInfo(token);
//}
}
//3.验证检查是否有黑名单的token缓存
string blacktoken = _redisClientService.GetStringKey($"wms_black_token_{logininfo.UserInfo.UcId}");
if (string.IsNullOrEmpty(blacktoken))
{
context.Response.StatusCode = 200;
await _next(context);
}
else
{
RemoveRedisLoginInfo(token);
context.Response.StatusCode = 403;
var result = JsonConvert.SerializeObject(new { status = 403, data = string.Empty, message = "拒绝用户证书试图访问此web站点,请与站点管理员联系以建立用户证书权限" });
context.Response.ContentType = "application/json;charset=utf-8";
await context.Response.WriteAsync(result);
}
}
if (context.Response.StatusCode == 401 || context.Response.StatusCode == 403)
{
//调用单点的退出接口
var dto = new LoginOutDto()
{
UcId = logininfo.UserInfo.UcId.ToString(),
SessionId = logininfo.UserInfo.SeesionId,
Token = logininfo.TokenInfo.Token,
AccessToken = logininfo.TokenInfo.PhpToken,
ExpiresIn = logininfo.TokenInfo.Expired
};
var res = await loginService.LoginOutAsync(dto);
return;
}
}
}
///
/// 过期,或者失效,移出token
///
///
private void RemoveRedisLoginInfo(string token)
{
if (!string.IsNullOrEmpty(token))
{
var info = _redisClientService.GetStringKey($"wms_login_{token}");
if (info != null)
{
_redisClientService.RemoveStringKey($"wms_login_{token}");
}
}
}
///
/// 刷新token
///
///
///
private bool RefreshToken(string OldToken, string RefreshToken, ILoginService _loginService)
{
_logger.LogInformation("RefreshToken:我在刷新登录--3");
var res = _loginService.RefreshToken(OldToken, RefreshToken);
if (!res.Result.Success)
return false;
else
return true;
}
}
}