1.定义中间件:(示例代码,不全)
using Dx.Csp.Infrastructure;
using Dx.Csp.Infrastructure.Enums;
using Dx.Csp.RoleManage;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Ocelot.Authorisation;
using Ocelot.Errors;
using Ocelot.Logging;
using Ocelot.Middleware;
using Ocelot.Responses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Dx.Csp.PermissionManage;
using Dx.Csp.AccountNoManage;
using Dx.Csp.QualificationManage;
using Dx.Csp.Infrastructure.Result;
namespace Dx.CspGateway.Middleware
{
public class AuthorizationCustomMiddleware : OcelotMiddleware
{
private readonly RequestDelegate _next;
private readonly IClaimsAuthoriser _claimsAuthoriser;
private readonly IScopesAuthoriser _scopesAuthoriser;
private IUrlAscriptionPermissionService _urlAscriptionPermissionService;
private IRoleManageService _roleManageService;
private IAccountNoManageService _accountNoManageService;
private IConfiguration _configuration;
private IBusinessQualificationsService _businessQualificationsService;
public AuthorizationCustomMiddleware(
IOcelotLoggerFactory loggerFactory,
RequestDelegate next,
IClaimsAuthoriser claimsAuthoriser,
IScopesAuthoriser scopesAuthoriser,
IUrlAscriptionPermissionService urlAscriptionPermissionService,
IRoleManageService roleManageService,
IAccountNoManageService accountNoManageService,
IBusinessQualificationsService businessQualificationsService,
IConfiguration configuration
) : base(loggerFactory.CreateLogger<AuthorizationCustomMiddleware>())
{
_businessQualificationsService = businessQualificationsService;
_accountNoManageService = accountNoManageService;
_urlAscriptionPermissionService = urlAscriptionPermissionService;
_next = next;
_claimsAuthoriser = claimsAuthoriser;
_scopesAuthoriser = scopesAuthoriser;
_roleManageService = roleManageService;
_configuration = configuration;
}
public async Task Invoke(HttpContext httpContext)
{
var downstreamRequest = httpContext.Items.DownstreamRequest();
var downstreamReRoute = httpContext.Items.DownstreamRoute();
//检查是否认证
if (!httpContext.User.Identity.IsAuthenticated)
{
//检查是否为注册,登录,验证码等不需要进行鉴权的url,否直接响应失败
await IsNotAuthenticated(httpContext, downstreamRequest);
return;
}
//检查账号状态
if (!await CheckAccountAsync(httpContext))
{
httpContext.Items.UpsertErrors(new List<Error> { new UnauthorisedError($"账号停用") });
return;
}
//获取客户信息检查,运营平台,管理平台
var ascription = httpContext.User.Claims.SingleOrDefault(c => c.Type == ClaimNameTypes.Ascription).Value;
var accountAscription = (AccountAscription)Convert.ToInt32(ascription);
if (accountAscription == AccountAscription.OperationPlatform)//运营平台
{
await OperationAuthrazition(httpContext, downstreamRequest);
return;
}
//管理平台
await ManageAuthrazition(httpContext, downstreamRequest);
return;
}
}
}
2.定义扩展方法
using Dx.CspGateway.Middleware; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Dx.Csp.OcelotGateway { public static class AuthorizationCustomMiddlewareExtensions { public static IApplicationBuilder UseAuthorizationCustom(this IApplicationBuilder builder) { return builder.UseMiddleware<AuthorizationCustomMiddleware>(); } public static void UseIfNotNull(this IApplicationBuilder builder, Func<HttpContext, Func<Task>, Task> middleware) { if (middleware != null) { builder.Use(middleware); } } } }
3.使用Ocelot
app.UseOcelot((builder, pipelineConfiguration) => { builder.UseDownstreamContextMiddleware(); // This is registered to catch any global exceptions that are not handled // It also sets the Request Id if anything is set globally builder.UseExceptionHandlerMiddleware(); // If the request is for websockets upgrade we fork into a different pipeline builder.MapWhen(httpContext => httpContext.WebSockets.IsWebSocketRequest, wenSocketsApp => { wenSocketsApp.UseDownstreamRouteFinderMiddleware(); wenSocketsApp.UseMultiplexingMiddleware(); wenSocketsApp.UseDownstreamRequestInitialiser(); wenSocketsApp.UseLoadBalancingMiddleware(); wenSocketsApp.UseDownstreamUrlCreatorMiddleware(); wenSocketsApp.UseWebSocketsProxyMiddleware(); }); // Allow the user to respond with absolutely anything they want. builder.UseIfNotNull(pipelineConfiguration.PreErrorResponderMiddleware); // This is registered first so it can catch any errors and issue an appropriate response builder.UseResponderMiddleware(); // Then we get the downstream route information builder.UseDownstreamRouteFinderMiddleware(); // Multiplex the request if required builder.UseMultiplexingMiddleware(); // This security module, IP whitelist blacklist, extended security mechanism builder.UseSecurityMiddleware(); //Expand other branch pipes if (pipelineConfiguration.MapWhenOcelotPipeline != null) { foreach (var pipeline in pipelineConfiguration.MapWhenOcelotPipeline) { // todo why is this asking for an app app? app.MapWhen(pipeline.Key, pipeline.Value); } } // Now we have the ds route we can transform headers and stuff? builder.UseHttpHeadersTransformationMiddleware(); // Initialises downstream request builder.UseDownstreamRequestInitialiser(); // We check whether the request is ratelimit, and if there is no continue processing builder.UseRateLimiting(); // This adds or updates the request id (initally we try and set this based on global config in the error handling middleware) // If anything was set at global level and we have a different setting at re route level the global stuff will be overwritten // 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. builder.UseRequestIdMiddleware(); // Allow pre authentication logic. The idea being people might want to run something custom before what is built in. builder.UseIfNotNull(pipelineConfiguration.PreAuthenticationMiddleware); // Now we know where the client is going to go we can authenticate them. // We allow the ocelot middleware to be overriden by whatever the // user wants if (pipelineConfiguration.AuthenticationMiddleware == null) { app.UseAuthenticationMiddleware(); } else { app.Use(pipelineConfiguration.AuthenticationMiddleware); } // The next thing we do is look at any claims transforms in case this is important for authorisation builder.UseClaimsToClaimsMiddleware(); // Allow pre authorisation logic. The idea being people might want to run something custom before what is built in. builder.UseIfNotNull(pipelineConfiguration.PreAuthorisationMiddleware); // Now we have authenticated and done any claims transformation we // can authorise the request // We allow the ocelot middleware to be overriden by whatever the // user wants if (pipelineConfiguration.AuthorisationMiddleware == null) { builder.UseAuthorisationMiddleware(); } else { builder.Use(pipelineConfiguration.AuthorisationMiddleware); } // Now we can run the claims to headers transformation middleware builder.UseClaimsToHeadersMiddleware(); // Allow the user to implement their own query string manipulation logic builder.UseIfNotNull(pipelineConfiguration.PreQueryStringBuilderMiddleware); // Now we can run any claims to query string transformation middleware builder.UseClaimsToQueryStringMiddleware(); builder.UseClaimsToDownstreamPathMiddleware(); // Get the load balancer for this request builder.UseLoadBalancingMiddleware(); // This takes the downstream route we retrieved earlier and replaces any placeholders with the variables that should be used builder.UseDownstreamUrlCreatorMiddleware(); // Not sure if this is the best place for this but we use the downstream url // as the basis for our cache key. builder.UseOutputCacheMiddleware(); builder.UseAuthorizationCustom(); //注意UseAuthorizationCustom为自己定义中间件,必须放在UseHttpRequesterMiddleware上方, //否则请求是先走url对应的程序而后才会走自定义中间件 //We fire off the request and set the response on the scoped data repo builder.UseHttpRequesterMiddleware(); builder.Build(); }).Wait();
4.以上除自定义中间件外,均由UseOcelot()源码中复制而来;
原文:https://www.cnblogs.com/rengke2002/p/14797533.html