AllowAnonymousMiddleware.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Authentication;
  3. using Ocelot.Configuration;
  4. using Ocelot.Logging;
  5. using Ocelot.Middleware;
  6. using System.Threading.Tasks;
  7. using Ocelot.DownstreamRouteFinder.Middleware;
  8. using Microsoft.Extensions.Configuration;
  9. using Microsoft.Extensions.Caching.Memory;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. namespace QM.Gateway.Uses
  13. {
  14. /// <summary>
  15. /// 中间件,授权白名单
  16. /// </summary>
  17. public class AllowAnonymousMiddleware : OcelotMiddleware
  18. {
  19. private readonly RequestDelegate _next;
  20. private readonly IConfiguration _configuration;
  21. private readonly IMemoryCache _memoryCache;
  22. public AllowAnonymousMiddleware(RequestDelegate next,
  23. IConfiguration configuration,
  24. IMemoryCache memoryCache,
  25. IOcelotLoggerFactory loggerFactory)
  26. : base(loggerFactory.CreateLogger<AuthenticationMiddleware>())
  27. {
  28. _next = next;
  29. _configuration = configuration;
  30. _memoryCache = memoryCache;
  31. }
  32. public async Task Invoke(HttpContext httpContext)
  33. {
  34. var downstreamRoute = httpContext.Items.DownstreamRoute();
  35. //添加配置,如果路由为白名单就直接过
  36. if (IsAllowAnonymous(httpContext))
  37. {
  38. Logger.LogInformation($"路由白名单:{httpContext.Request.Path}");
  39. await _next.Invoke(httpContext);
  40. }
  41. else if (httpContext.Request.Method.ToUpper() != "OPTIONS" && IsAuthenticatedRoute(downstreamRoute))
  42. {
  43. Logger.LogInformation($"{httpContext.Request.Path} is an authenticated route. {MiddlewareName} checking if client is authenticated");
  44. var result = await httpContext.AuthenticateAsync(downstreamRoute.AuthenticationOptions.AuthenticationProviderKey);
  45. httpContext.User = result.Principal;
  46. if (httpContext.User.Identity.IsAuthenticated)
  47. {
  48. Logger.LogInformation($"Client has been authenticated for {httpContext.Request.Path}");
  49. await _next.Invoke(httpContext);
  50. }
  51. else
  52. {
  53. var error = new UnauthenticatedError(
  54. $"Request for authenticated route {httpContext.Request.Path} by {httpContext.User.Identity.Name} was unauthenticated");
  55. Logger.LogWarning($"Client has NOT been authenticated for {httpContext.Request.Path} and pipeline error set. {error}");
  56. httpContext.Items.SetError(error);
  57. }
  58. }
  59. else
  60. {
  61. Logger.LogInformation($"No authentication needed for {httpContext.Request.Path}");
  62. await _next.Invoke(httpContext);
  63. }
  64. }
  65. private static bool IsAuthenticatedRoute(DownstreamRoute route)
  66. {
  67. return route.IsAuthenticated;
  68. }
  69. /// <summary>
  70. /// 是否白名单
  71. /// </summary>
  72. /// <param name="httpContext"></param>
  73. /// <returns></returns>
  74. private bool IsAllowAnonymous(HttpContext httpContext)
  75. {
  76. var alls = _memoryCache.Get("AllowAnonymous");
  77. List<string> list = new List<string>();
  78. if(alls == null)
  79. {
  80. IConfigurationSection myArraySection = _configuration.GetSection("AllowAnonymous");
  81. list = myArraySection.AsEnumerable().Where(t => t.Value != null).Select(t => t.Value.ToLower().Trim()).ToList();
  82. _memoryCache.Set("AllowAnonymous", list);
  83. }
  84. else
  85. {
  86. list = alls as List<string>;
  87. }
  88. var res = list.Contains(httpContext.Request.Path.Value.ToLower().Trim());
  89. return res;
  90. }
  91. }
  92. }