using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using Shentun.Utilities; using Shentun.Utilities.Encrypt; using Shentun.Utilities.Enums; using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; namespace Shentun.WebApi.Service { /// /// 授权中间件 /// public class JwtMiddleware { private readonly RequestDelegate _next; /// /// /// /// public JwtMiddleware(RequestDelegate next) { _next = next; } /// /// /// /// /// public Task Invoke(HttpContext httpContext) { //检测是否包含'Authorization'请求头,如果不包含则直接放行 if (!httpContext.Request.Headers.ContainsKey("Authorization")) { return _next(httpContext); } var tokenHeader = httpContext.Request.Headers["Authorization"]; JwtHelper jwtHelper = new JwtHelper(); //if (!httpContext.Request.Headers.ContainsKey("SessionKey")) //{ // throw new Exception("必须提供会话密匙键"); //} //var sessionKey = httpContext.Request.Headers["SessionKey"].ToString(); //var cache = httpContext.RequestServices.GetRequiredService(); //string securityKey; //if (!cache.TryGetValue(sessionKey, out securityKey)) //{ // throw new Exception("会话密匙键无效"); //} //jwtHelper.SecurityKey = securityKey; //从令牌中获取token try { //var jwtConfig = new JwtConfig(); //string securityKey = jwtConfig.SecurityKey.Substring(0,16); //tokenHeader = AESHelper.Decode(tokenHeader, securityKey); JwtSecurityToken jwtSecurityToken = jwtHelper.GetValidatedToken(tokenHeader); //授权 var claims = jwtSecurityToken.Claims; var identity = new ClaimsIdentity(claims); var principal = new ClaimsPrincipal(identity); httpContext.User = principal; //设置最后访问时间 var userId = httpContext.User.FindFirst(ClaimTypes.Sid).Value; var clientAppTypeStr = httpContext.User.FindFirst("ClientAppType").Value; if (!string.IsNullOrWhiteSpace(userId) && !string.IsNullOrWhiteSpace(clientAppTypeStr)) { var cache = ServiceLocator.Instance.GetService(); if (cache != null) { //设置最后登录时间,缓存比token有效时间多10分钟 //LogHelper.Logger.LogDebug($"clientAppType:{clientAppType}"); ClientAppType clientAppType; if (Enum.TryParse(clientAppTypeStr, out clientAppType)) { cache.Set($"userLastAccessKey{userId}", DateTime.UtcNow, TimeSpan.FromMinutes(10 + (int)jwtHelper.GetExpiration(clientAppType))); } } } } catch (Exception ex) { if (ex.Message.Contains("IDX10223")) { var response = httpContext.Response; response.ContentType = "application/json"; response.StatusCode = 401; } else { throw ex; } } return _next(httpContext); } } }