UseOcelotPipelineExtensions.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using Ocelot.QueryStrings.Middleware;
  2. using Ocelot.RateLimit.Middleware;
  3. using Ocelot.Request.Middleware;
  4. using Ocelot.Requester.Middleware;
  5. using Ocelot.RequestId.Middleware;
  6. using Ocelot.Responder.Middleware;
  7. using Ocelot.Security.Middleware;
  8. using Ocelot.Authentication.Middleware;
  9. using Ocelot.Authorization.Middleware;
  10. using Ocelot.Cache.Middleware;
  11. using Ocelot.Claims.Middleware;
  12. using Ocelot.DownstreamRouteFinder.Middleware;
  13. using Ocelot.DownstreamUrlCreator.Middleware;
  14. using Ocelot.Errors.Middleware;
  15. using Ocelot.Headers.Middleware;
  16. using Ocelot.LoadBalancer.Middleware;
  17. using System;
  18. using System.Threading.Tasks;
  19. using Ocelot.DownstreamPathManipulation.Middleware;
  20. using Microsoft.AspNetCore.Builder;
  21. using Microsoft.AspNetCore.Http;
  22. using Ocelot.WebSockets.Middleware;
  23. using Ocelot.Multiplexer;
  24. using Ocelot.Middleware;
  25. namespace QM.Gateway.Uses
  26. {
  27. public static class UseOcelotPipelineExtensions
  28. {
  29. public static RequestDelegate UseBuildOcelotPipeline(this IApplicationBuilder app,
  30. OcelotPipelineConfiguration pipelineConfiguration)
  31. {
  32. // this sets up the downstream context and gets the config
  33. app.UseDownstreamContextMiddleware();
  34. // This is registered to catch any global exceptions that are not handled
  35. // It also sets the Request Id if anything is set globally
  36. app.UseExceptionHandlerMiddleware();
  37. // If the request is for websockets upgrade we fork into a different pipeline
  38. app.MapWhen(httpContext => httpContext.WebSockets.IsWebSocketRequest,
  39. wenSocketsApp =>
  40. {
  41. wenSocketsApp.UseDownstreamRouteFinderMiddleware();
  42. wenSocketsApp.UseMultiplexingMiddleware();
  43. wenSocketsApp.UseDownstreamRequestInitialiser();
  44. wenSocketsApp.UseLoadBalancingMiddleware();
  45. wenSocketsApp.UseDownstreamUrlCreatorMiddleware();
  46. wenSocketsApp.UseWebSocketsProxyMiddleware();
  47. });
  48. // Allow the user to respond with absolutely anything they want.
  49. app.UseIfNotNull(pipelineConfiguration.PreErrorResponderMiddleware);
  50. // This is registered first so it can catch any errors and issue an appropriate response
  51. app.UseResponderMiddleware();
  52. // Then we get the downstream route information
  53. app.UseDownstreamRouteFinderMiddleware();
  54. // Multiplex the request if required
  55. app.UseMultiplexingMiddleware();
  56. // This security module, IP whitelist blacklist, extended security mechanism
  57. app.UseSecurityMiddleware();
  58. //Expand other branch pipes
  59. if (pipelineConfiguration.MapWhenOcelotPipeline != null)
  60. {
  61. foreach (var pipeline in pipelineConfiguration.MapWhenOcelotPipeline)
  62. {
  63. // todo why is this asking for an app app?
  64. app.MapWhen(pipeline.Key, pipeline.Value);
  65. }
  66. }
  67. // Now we have the ds route we can transform headers and stuff?
  68. app.UseHttpHeadersTransformationMiddleware();
  69. // Initialises downstream request
  70. app.UseDownstreamRequestInitialiser();
  71. // We check whether the request is ratelimit, and if there is no continue processing
  72. app.UseRateLimiting();
  73. // This adds or updates the request id (initally we try and set this based on global config in the error handling middleware)
  74. // If anything was set at global level and we have a different setting at re route level the global stuff will be overwritten
  75. // This means you can get a scenario where you have a different request id from the first piece of middleware to the request id middleware.
  76. app.UseRequestIdMiddleware();
  77. // Allow pre authentication logic. The idea being people might want to run something custom before what is built in.
  78. app.UseIfNotNull(pipelineConfiguration.PreAuthenticationMiddleware);
  79. //单点登录
  80. //app.UseMiddleware<SingleLoginMiddleware>();
  81. // Now we know where the client is going to go we can authenticate them.
  82. // We allow the ocelot middleware to be overriden by whatever the
  83. // user wants
  84. if (pipelineConfiguration.AuthenticationMiddleware == null)
  85. {
  86. //app.UseAuthenticationMiddleware(); //原始
  87. //TODO
  88. //添加自定义中间件
  89. app.UseMiddleware<AllowAnonymousMiddleware>();
  90. }
  91. else
  92. {
  93. app.Use(pipelineConfiguration.AuthenticationMiddleware);
  94. }
  95. // The next thing we do is look at any claims transforms in case this is important for authorization
  96. app.UseClaimsToClaimsMiddleware();
  97. // Allow pre authorization logic. The idea being people might want to run something custom before what is built in.
  98. app.UseIfNotNull(pipelineConfiguration.PreAuthorizationMiddleware);
  99. // Now we have authenticated and done any claims transformation we
  100. // can authorize the request
  101. // We allow the ocelot middleware to be overriden by whatever the
  102. // user wants
  103. if (pipelineConfiguration.AuthorizationMiddleware == null)
  104. {
  105. app.UseAuthorizationMiddleware();
  106. }
  107. else
  108. {
  109. app.Use(pipelineConfiguration.AuthorizationMiddleware);
  110. }
  111. // Now we can run the claims to headers transformation middleware
  112. app.UseClaimsToHeadersMiddleware();
  113. // Allow the user to implement their own query string manipulation logic
  114. app.UseIfNotNull(pipelineConfiguration.PreQueryStringBuilderMiddleware);
  115. // Now we can run any claims to query string transformation middleware
  116. app.UseClaimsToQueryStringMiddleware();
  117. app.UseClaimsToDownstreamPathMiddleware();
  118. // Get the load balancer for this request
  119. app.UseLoadBalancingMiddleware();
  120. // This takes the downstream route we retrieved earlier and replaces any placeholders with the variables that should be used
  121. app.UseDownstreamUrlCreatorMiddleware();
  122. // Not sure if this is the best place for this but we use the downstream url
  123. // as the basis for our cache key.
  124. app.UseOutputCacheMiddleware();
  125. //We fire off the request and set the response on the scoped data repo
  126. app.UseHttpRequesterMiddleware();
  127. return app.Build();
  128. }
  129. private static void UseIfNotNull(this IApplicationBuilder builder,
  130. Func<HttpContext, Func<Task>, Task> middleware)
  131. {
  132. if (middleware != null)
  133. {
  134. builder.Use(middleware);
  135. }
  136. }
  137. }
  138. }