• 中间件


    WebHost,请求进来,ProcessRequest,request请求出来,先经过下列中间件,由next(context)层层传递,再response返回

    app.UseCorrelationId()

    request: request没有header,则返回一个Guid.NewGuid().ToString("N"),若有取Headers【X-Correlation-Id】,若非空则返回,否则生成一个,给header设置一个头,则返回此头

    response:检查并确定给response返回一个correlationId


    app.UseVirtualFiles();

    提供静态文件StaticFileOptions.FileProvider


    app.UseAbpRequestLocalization();

    获取RequestLocalizationOptions,并执行LocalizationOptions的委托  IAbpRequestLocalizationOptionsProvider.InitLocalizationOptions

    创建RequestLocalizationMiddleware,导入LocalizationOptions和_loggerFactory


    app.UseRouting();

    public static IApplicationBuilder UseRouting(this IApplicationBuilder builder)
            {
                if (builder == null)
                {
                    throw new ArgumentNullException(nameof(builder));
                }
    
                VerifyRoutingServicesAreRegistered(builder);
    
                var endpointRouteBuilder = new DefaultEndpointRouteBuilder(builder);
                builder.Properties[EndpointRouteBuilder] = endpointRouteBuilder;
    
                return builder.UseMiddleware<EndpointRoutingMiddleware>(endpointRouteBuilder);
            }
      {
                // There's already an endpoint, skip maching completely
                var endpoint = httpContext.GetEndpoint();
                if (endpoint != null)
                {
                    Log.MatchSkipped(_logger, endpoint);
                    return _next(httpContext);
                }
    
                // There's an inherent race condition between waiting for init and accessing the matcher
                // this is OK because once `_matcher` is initialized, it will not be set to null again.
                var matcherTask = InitializeAsync();
                if (!matcherTask.IsCompletedSuccessfully)
                {
                    return AwaitMatcher(this, httpContext, matcherTask);
                }
    
                var matchTask = matcherTask.Result.MatchAsync(httpContext);
                if (!matchTask.IsCompletedSuccessfully)
                {
                    return AwaitMatch(this, httpContext, matchTask);
                }
    
                return SetRoutingAndContinue(httpContext);
    
                // Awaited fallbacks for when the Tasks do not synchronously complete
                static async Task AwaitMatcher(EndpointRoutingMiddleware middleware, HttpContext httpContext, Task<Matcher> matcherTask)
                {
                    var matcher = await matcherTask;
                    await matcher.MatchAsync(httpContext);
                    await middleware.SetRoutingAndContinue(httpContext);
                }
    
                static async Task AwaitMatch(EndpointRoutingMiddleware middleware, HttpContext httpContext, Task matchTask)
                {
                    await matchTask;
                    await middleware.SetRoutingAndContinue(httpContext);
                }
    
            }

    app.UseAuthentication();

    创建HttpContext.User,Abp Vnext提供的ICurrentUser就是来源HttpContext.User?Thead.ClaimsPrincipals

     public async Task Invoke(HttpContext context)
            {
                context.Features.Set<IAuthenticationFeature>(new AuthenticationFeature
                {
                    OriginalPath = context.Request.Path,
                    OriginalPathBase = context.Request.PathBase
                });
                // Give any IAuthenticationRequestHandler schemes a chance to handle the request
                var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
                foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
                {
                    var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler;
                    if (handler != null && await handler.HandleRequestAsync())
                    {
                        return;
                    }
                }
                var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
                if (defaultAuthenticate != null)
                {
                    var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
                    if (result?.Principal != null)
                    {
                        context.User = result.Principal;
                    }
                }
                await _next(context);
            }

    app.UseMiddleware<FakeAuthenticationMiddleware>();

    认证:提供一个fake

     new ClaimsIdentity(_fakeUserClaims.Claims, "FakeSchema")


    app.UseAuthorization();

     public async Task Invoke(HttpContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }
    
                var endpoint = context.GetEndpoint();
    
                if (endpoint != null)
                {
                    // EndpointRoutingMiddleware uses this flag to check if the Authorization middleware processed auth metadata on the endpoint.
                    // The Authorization middleware can only make this claim if it observes an actual endpoint.
                    context.Items[AuthorizationMiddlewareInvokedWithEndpointKey] = AuthorizationMiddlewareWithEndpointInvokedValue;
                }
    
                // IMPORTANT: Changes to authorization logic should be mirrored in MVC's AuthorizeFilter
                var authorizeData = endpoint?.Metadata.GetOrderedMetadata<IAuthorizeData>() ?? Array.Empty<IAuthorizeData>();
                var policy = await AuthorizationPolicy.CombineAsync(_policyProvider, authorizeData);
                if (policy == null)
                {
                    await _next(context);
                    return;
                }
    
                // Policy evaluator has transient lifetime so it fetched from request services instead of injecting in constructor
                var policyEvaluator = context.RequestServices.GetRequiredService<IPolicyEvaluator>();
    
                var authenticateResult = await policyEvaluator.AuthenticateAsync(policy, context);
    
                // Allow Anonymous skips all authorization
                if (endpoint?.Metadata.GetMetadata<IAllowAnonymous>() != null)
                {
                    await _next(context);
                    return;
                }
    
                // Note that the resource will be null if there is no matched endpoint
                var authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult, context, resource: endpoint);
    
                if (authorizeResult.Challenged)
                {
                    if (policy.AuthenticationSchemes.Any())
                    {
                        foreach (var scheme in policy.AuthenticationSchemes)
                        {
                            await context.ChallengeAsync(scheme);
                        }
                    }
                    else
                    {
                        await context.ChallengeAsync();
                    }
    
                    return;
                }
                else if (authorizeResult.Forbidden)
                {
                    if (policy.AuthenticationSchemes.Any())
                    {
                        foreach (var scheme in policy.AuthenticationSchemes)
                        {
                            await context.ForbidAsync(scheme);
                        }
                    }
                    else
                    {
                        await context.ForbidAsync();
                    }
    
                    return;
                }
    
                await _next(context);
            }

    app.UseAuditing();

    判断请求是否需要写审计log  =》可配置,不允许匿名访问而且用户没有认证 不审计, get请求不写审记

    需要的话,创建一个IAuditLogSaveHandle,

    response: 保存 scope.SaveAsync()


    app.UseUnitOfWork();

    1、先创建一个AbpExceptionHandlingMiddleware

    如果出错,则catch到错误,并返回错误

    2、工作单元中间件:

    创建一个Reserve的保留工作单元

     在AbpUowActionFilter,则启用工作单元

            private static void AddFilters(MvcOptions options)
            {
                options.Filters.AddService(typeof(AbpAuditActionFilter));
                options.Filters.AddService(typeof(AbpFeatureActionFilter));
                options.Filters.AddService(typeof(AbpValidationActionFilter));
                options.Filters.AddService(typeof(AbpUowActionFilter));
                options.Filters.AddService(typeof(AbpExceptionFilter));
            }

    app.UseMvcWithDefaultRouteAndArea();

     首先经过路由规则的匹配,找到最符合条件的的IRouter,然后调用IRouter.RouteAsync来设置RouteContext.Handler,最后把请求交给RouteContext.Handler来处理。

    在MVC中提供了两个IRouter实现,分别如下:MvcAttributeRouteHandler,MvcRouteHandler

    ApplicationModel->ControllerModel->ActionModel

    通过路由和动作匹配后,最终会得到跟当前请求最匹配的一个ActionDescriptor,然后通过IActionInvoker执行动作。

    创建Action,由IActionInvokerFactory负责创建,

    依赖ILoggerFactory,

    SaveTempDataFilter

    AbpAuditActionFilter  》需要用户,租户,时间,序列化,客户端等服务支持

    只处理ControllerAction

    AbpFeatureActionFilter

    只处理ControllerAction,不处理


    AbpValidationActionFilter
    AbpUowActionFilter
    AbpExceptionFilter 》IExceptionToErrorInfoConverter,IHttpExceptionStatusCodeFinder,IJsonSerializer

    再创建

    FeatureTestController (目标)

    由于此服务注册了拦截器Feature,由于拦截器负责代理

    ProcessRequest(WebHost)

    RequestServicesContainerMiddleware:给请求上下文绑定容器,它所做的事情就是创建一个范围内的服务提供者并在请求结束时销毁它,当全部的Middleware都被执行完后,并返回到了RequestServiceContainerMiddleware,Scoped Container会被销毁通过"Using"

    HostFilteringMiddleware

    ForwardHeaderMiddleWare

    IISMiddleWare

  • 相关阅读:
    C语言计时
    time模块
    大端对齐 和小端对齐
    python之生成器与迭代器
    python之字符串反转
    简单排序
    Python学习笔记——切片
    Python学习笔记——函数(二)
    Python学习笔记——函数(一)
    Python学习笔记——字典(dict)
  • 原文地址:https://www.cnblogs.com/cloudsu/p/11856269.html
Copyright © 2020-2023  润新知