JwtAuthMiddleware.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using Infrastructure;
  2. using Infrastructure.Model;
  3. using Microsoft.AspNetCore.Authorization;
  4. using Microsoft.AspNetCore.Http;
  5. using Microsoft.Extensions.Logging;
  6. using System.Security.Claims;
  7. using ZR.Common;
  8. namespace ZR.ServiceCore.Middleware
  9. {
  10. /// <summary>
  11. /// jwt认证中间件
  12. /// </summary>
  13. public class JwtAuthMiddleware
  14. {
  15. private readonly RequestDelegate _next;
  16. private readonly ILogger<JwtAuthMiddleware> _logger;
  17. private static readonly string[] _whitelistPaths = new[]
  18. {
  19. ".png",
  20. "/msgHub"
  21. };
  22. public JwtAuthMiddleware(RequestDelegate next, ILogger<JwtAuthMiddleware> logger)
  23. {
  24. _next = next;
  25. _logger = logger;
  26. }
  27. public async Task InvokeAsync(HttpContext context)
  28. {
  29. var path = context.Request.Path.Value;
  30. // 如果请求是带扩展名的(即包含 .)
  31. if (path.Contains('.'))
  32. {
  33. await _next(context);
  34. return;
  35. }
  36. if (_whitelistPaths.Any(p => path.StartsWith(p, StringComparison.OrdinalIgnoreCase)))
  37. {
  38. await _next(context);
  39. return;
  40. }
  41. var endpoint = context.GetEndpoint();
  42. var allowAnonymous = endpoint?.Metadata?.GetMetadata<AllowAnonymousAttribute>() != null;
  43. if (allowAnonymous)
  44. {
  45. await _next(context);
  46. return;
  47. }
  48. string ip = HttpContextExtension.GetClientUserIp(context);
  49. string url = context.Request.Path;
  50. string osType = context.Request.Headers["os"];
  51. TokenModel loginUser = JwtUtil.GetLoginUser(context);
  52. if (loginUser != null)
  53. {
  54. var now = DateTime.UtcNow;
  55. var ts = loginUser.ExpireTime - now;
  56. var cacheKey = $"token_{loginUser.UserId}";
  57. if (!CacheHelper.Exists(cacheKey) && ts.TotalMinutes < 5 && ts.TotalMinutes > 0)
  58. {
  59. var newToken = JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser));
  60. CacheHelper.SetCache(cacheKey, cacheKey, 1);
  61. if (!string.IsNullOrEmpty(osType))
  62. {
  63. context.Response.Headers.Append("Access-Control-Expose-Headers", "X-Refresh-Token");
  64. }
  65. context.Response.Headers.Append("X-Refresh-Token", newToken);
  66. _logger.LogInformation($"刷新Token: {loginUser.UserName}");
  67. }
  68. // 还可以挂载到 context.User
  69. var identity = new ClaimsIdentity(JwtUtil.AddClaims(loginUser), "jwt");
  70. context.User = new ClaimsPrincipal(identity);
  71. await _next(context);
  72. }
  73. else
  74. {
  75. string msg = $"请求访问[{url}]失败,Token无效或未登录";
  76. _logger.LogWarning(msg);
  77. //context.Response.StatusCode = StatusCodes.Status401Unauthorized;
  78. await context.Response.WriteAsJsonAsync(ApiResult.Error(ResultCode.DENY, msg));
  79. }
  80. }
  81. }
  82. }