You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
4.1 KiB

  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.Extensions.Caching.Memory;
  3. using Microsoft.Extensions.DependencyInjection;
  4. using Microsoft.Extensions.Logging;
  5. using Microsoft.IdentityModel.Tokens;
  6. using Shentun.Utilities;
  7. using Shentun.Utilities.Encrypt;
  8. using Shentun.Utilities.Enums;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.IdentityModel.Tokens.Jwt;
  12. using System.Linq;
  13. using System.Security.Claims;
  14. using System.Threading.Tasks;
  15. namespace Shentun.WebApi.Service
  16. {
  17. /// <summary>
  18. /// 授权中间件
  19. /// </summary>
  20. public class JwtMiddleware
  21. {
  22. private readonly RequestDelegate _next;
  23. /// <summary>
  24. ///
  25. /// </summary>
  26. /// <param name="next"></param>
  27. public JwtMiddleware(RequestDelegate next)
  28. {
  29. _next = next;
  30. }
  31. /// <summary>
  32. ///
  33. /// </summary>
  34. /// <param name="httpContext"></param>
  35. /// <returns></returns>
  36. public Task Invoke(HttpContext httpContext)
  37. {
  38. //检测是否包含'Authorization'请求头,如果不包含则直接放行
  39. if (!httpContext.Request.Headers.ContainsKey("Authorization"))
  40. {
  41. return _next(httpContext);
  42. }
  43. var tokenHeader = httpContext.Request.Headers["Authorization"];
  44. JwtHelper jwtHelper = new JwtHelper();
  45. //if (!httpContext.Request.Headers.ContainsKey("SessionKey"))
  46. //{
  47. // throw new Exception("必须提供会话密匙键");
  48. //}
  49. //var sessionKey = httpContext.Request.Headers["SessionKey"].ToString();
  50. //var cache = httpContext.RequestServices.GetRequiredService<IMemoryCache>();
  51. //string securityKey;
  52. //if (!cache.TryGetValue(sessionKey, out securityKey))
  53. //{
  54. // throw new Exception("会话密匙键无效");
  55. //}
  56. //jwtHelper.SecurityKey = securityKey;
  57. //从令牌中获取token
  58. try
  59. {
  60. //var jwtConfig = new JwtConfig();
  61. //string securityKey = jwtConfig.SecurityKey.Substring(0,16);
  62. //tokenHeader = AESHelper.Decode(tokenHeader, securityKey);
  63. JwtSecurityToken jwtSecurityToken = jwtHelper.GetValidatedToken(tokenHeader);
  64. //授权
  65. var claims = jwtSecurityToken.Claims;
  66. var identity = new ClaimsIdentity(claims);
  67. var principal = new ClaimsPrincipal(identity);
  68. httpContext.User = principal;
  69. //设置最后访问时间
  70. var userId = httpContext.User.FindFirst(ClaimTypes.Sid).Value;
  71. var clientAppTypeStr = httpContext.User.FindFirst("ClientAppType").Value;
  72. if (!string.IsNullOrWhiteSpace(userId) && !string.IsNullOrWhiteSpace(clientAppTypeStr))
  73. {
  74. var cache = ServiceLocator.Instance.GetService<IMemoryCache>();
  75. if (cache != null)
  76. {
  77. //设置最后登录时间,缓存比token有效时间多10分钟
  78. //LogHelper.Logger.LogDebug($"clientAppType:{clientAppType}");
  79. ClientAppType clientAppType;
  80. if (Enum.TryParse(clientAppTypeStr, out clientAppType))
  81. {
  82. cache.Set<DateTime>($"userLastAccessKey{userId}", DateTime.UtcNow,
  83. TimeSpan.FromMinutes(10 + (int)jwtHelper.GetExpiration(clientAppType)));
  84. }
  85. }
  86. }
  87. }
  88. catch (Exception ex)
  89. {
  90. if (ex.Message.Contains("IDX10223"))
  91. {
  92. var response = httpContext.Response;
  93. response.ContentType = "application/json";
  94. response.StatusCode = 401;
  95. }
  96. else
  97. {
  98. throw ex;
  99. }
  100. }
  101. return _next(httpContext);
  102. }
  103. }
  104. }