皮皮网

【博克源码】【值班源码 php】【xposed 源码 分析】aspcore源码

2024-11-19 16:48:58 来源:aspnet框架源码

1.ASP.NET Core配置系列五
2.ASP.NET Core认证原理和实现
3.asp.net core依赖注入原理
4.理解ASP.NET Core-文件服务器(File Server)
5.认识ASP.NET Core / Host及其配置解析
6.Asp-Net-Core开发笔记:使用RateLimit中间件实现接口限流

aspcore源码

ASP.NET Core配置系列五

       在开发ASP.NET Core应用程序时,异常处理是至关重要的。本文将详细阐述如何在开发环境中添加异常处理中间件以及在不同环境下的异常处理策略。

       首先,我们需要确保在运行应用程序时能捕获并处理异常。在浏览器输入指定URL时,博克源码若遇到异常,通常只会得到无响应的状态提示。为了获取更友好的异常消息,如资源不存在、无访问权限、资源不可用等,我们应当启用异常处理功能。

       在ASP.NET Core中,通常在Program类中添加ExceptionHandler中间件,并使用`UseDeveloperExceptionPage`方法生成HTML错误信息。对于特定的响应状态码错误,我们可以使用`app.UseStatusCodePages()`中间件进行处理。在`Program.cs`类中添加相关代码,并在运行前注释掉`ResponseEditingMiddleware`中间件。

       重新运行应用程序,并输入指定URL,将能够看到详细的值班源码 php错误页面,例如,当资源不存在引发异常时,页面将显示异常原因。如果在action方法中代码发生异常,如NullReferenceException,通过访问特定URL,能获得更详细的异常信息和堆栈跟踪。

       在不同的开发环境(如生产环境和开发环境)中,异常处理策略也有所不同。在生产环境中,我们可以添加一个action方法,当错误发生时调用它。在开发环境中,为了提供更详细的错误信息,我们可以创建错误视图。通过在`Program.cs`类中配置`UseExceptionHandler`中间件,并指定错误路径,如`/Home/Error`,可以在错误发生时调转到该action。

       对于appsettings.json文件的配置,它存储了数据库链接、全局变量以及其他ASP.NET Core应用程序的xposed 源码 分析配置信息。文件位于项目根目录下,包含了键值对,如`Key1: Microsoft`、`Key2: DotNet`等。在项目文件中创建`appsettings.json`文件,并根据需要添加配置节点,如中间件的启用状态。在`Program.cs`类中使用`app.Configuration()`方法读取配置文件,并根据配置注册相应的中间件。

       在Controller和View中访问appsettings.json,可以通过注入`IConfiguration`实现。在大型项目中,为避免直接访问过多的实体类,可从`appsettings.json`中提取所需的节点并转化为实体类,通过实体类访问配置文件中的键值对。为实现这一过程,首先创建包含节点的类,然后在`Program.cs`中使用`Configure`注册该类,之后在控制器中使用`IOptions`获取该类。

       在View中注入`IOptions`,允许在视图中使用配置文件中存储的值。通过`@settings.Value.PropertyName`可以访问属性。gec系统源码对于不同的开发和生产环境,可以创建两个不同的`appsettings`文件,如`appsettings.Production.json`和`appsettings.Development.json`。框架会根据当前环境自动选择相应的配置文件,从而实现环境间的配置隔离。

       综上所述,本文涵盖了ASP.NET Core配置系列的各个方面,从文件结构到中间件使用,再到环境间的配置差异,提供了全面的异常处理策略和配置管理方案。为了深入学习和实践,请参考源代码地址:github.com/bingbing-gui...,并加入技术群获取更多学习资源。

ASP.NET Core认证原理和实现

       é€šå¸¸åœ¨åº”用程序中,安全分为前后两个步骤:验证和授权。验证负责检查当前请求者的身份,而授权则根据上一步得到的身份决定当前请求者是否能够访问期望的资源。

        既然安全从验证开始,我们也就从验证开始介绍安全。

        我们先从比较简单的场景开始考虑,例如在 Web API 开发中,需要验证请求方是否提供了安全令牌,安全令牌是否有效。如果无效,那么 API 端应该拒绝提供服务。在命名空间 Microsoft.AspNetCore.Authentication 下,定义关于验证的核心接口。对应的程序集是 Microsoft.AspNetCore.Authentication.Abstractions.dll。

        在 ASP.NET 下,验证中包含 3 个基本操作:

        验证操作负责基于当前请求的上下文,使用来自请求中的信息,例如请求头、Cookie 等等来构造用户标识。构建的结果是一个 AuthenticateResult 对象,它指示了验证是否成功,如果成功的话,用户标识将可以在验证票据中找到。

        常见的验证包括:

        在授权管理阶段,如果用户没有得到验证,但所期望访问的资源要求必须得到验证的时候,授权服务会发出质询。例如,当匿名用户访问受限资源的时候,或者当用户点击登录链接的时候。授权服务会通过质询来相应用户。

        例如

        质询操作应该让用户知道应该使用何种验证机制来访问请求的资源。

        在授权管理阶段,如果用户已经通过了验证,但是对于其访问的资源并没有得到许可,此时会使用拒绝操作。

        例如:

        拒绝访问处理应该让用户知道:

        在这个场景下,可以看到,验证需要提供的基本功能就包括了验证和验证失败后的拒绝服务两个操作。在 ASP.NET Core 中,验证被称为 Authenticate,拒绝被称为 Forbid。 在供消费者访问的网站上,如果我们希望在验证失败后,不是像 API 一样直接返回一个错误页面,而是将用户导航到登录页面,那么,就还需要增加一个操作,这个操作的本质是希望用户再次提供安全凭据,在 ASP.NET Core 中,这个操作被称为 Challenge。这 3 个操作结合在一起,就是验证最基本的要求,以接口形式表示,就是 IAuthenticationHandler 接口,如下所示:

        验证的结果是一个 AuthenticateResult 对象。值得注意的是,它还提供了一个静态方法 NoResult() 用来返回没有得到结果,静态方法 Fail() 生成一个表示验证异常的结果,而 Success() 成功则需要提供验证票据。

        通过验证之后,会返回一个包含了请求者票据的验证结果。

        在 GitHub 中查看 AuthenticateResult 源码

        那么验证的信息来自哪里呢?除了前面介绍的 3 个操作之外,还要求一个初始化的操作 Initialize,通过这个方法来提供当前请求的上下文信息。

        在 GitHub 中查看 IAuthenticationHandler 定义

        有的时候,我们还希望提供登出操作,增加登出操作的接口被称为 IAuthenticationSignOutHandler。

        在 GitHub 中查看 IAuthenticationSignOutHandler 源码

        在登出的基础上,如果还希望提供登录操作,那么就是 IAuthenticationSignInHandler 接口。

        在 GitHub 中查看 IAuthenticationSignInHandler 源码

        直接实现接口还是比较麻烦的,在命名空间 Microsoft.AspNetCore.Authentication 下,微软提供了抽象基类 AuthenticationHandler 以方便验证控制器的开发,其它控制器可以从该控制器派生,以取得其提供的服务。

        通过类的定义可以看到,它使用了泛型。每个控制器应该有一个对应该控制器的配置选项,通过泛型来指定验证处理器所使用的配置类型,在构造函数中,可以看到它被用于获取对应的配置选项对象。

        在 GitHub 中查看 AuthenticationHandler 源码

        通过 InitializeAsync(),验证处理器可以获得当前请求的上下文对象 HttpContext。

        最终,作为抽象类的 ,希望派生类来完成这个验证任务,抽象方法 HandleAuthenticateAsync() 提供了扩展点。

        验证的结果是一个 AuthenticateResult。

        而拒绝服务则简单的多,直接在这个抽象基类中提供了默认实现。直接返回 HTTP 。

        剩下的一个也一样,提供了默认实现。直接返回 HTTP 响应。

        对于 JWT 来说,并不涉及到登入和登出,所以它需要从实现 IAuthenticationHandler 接口的抽象基类 AuthenticationHandler 派生出来即可。从 AuthenticationHandler 派生出来的 JwtBearerHandler 实现基于自己的配置选项 JwtBearerOptions。所以该类定义就变得如下所示,而构造函数显然配合了抽象基类的要求。

        在 GitHub 中查看 JwtBearerHandler 源码

        真正的验证则在 HandleAuthenticateAsync() 中实现。下面的代码是不是就很熟悉了,从请求头中获取附带的 JWT 访问令牌,然后验证该令牌的有效性,核心代码如下所示。

        在 GitHub 中查看 JwtBearerHandler 源码

        在 ASP.NET Core 中,你可以使用各种验证处理器,并不仅仅只能使用一个,验证控制器需要一个名称,它被看作该验证模式 Schema 的名称。Jwt 验证模式的默认名称就是 "Bearer",通过字符串常量 JwtBearerDefaults.AuthenticationScheme 定义。

        在 GitHub 中查看 JwtBearerDefaults 源码

        最终通过 AuthenticationBuilder 的扩展方法 AddJwtBearer() 将 Jwt 验证控制器注册到依赖注入的容器中。

        在 GitHub 中查看 JwtBearerExtensions 扩展方法源码

        一种验证处理器,加上对应的验证配置选项,我们再为它起一个名字,组合起来就成为一种验证架构 Schema。在 ASP.NET Core 中,可以注册多种验证架构。例如,授权策略可以使用架构的名称来指定所使用的验证架构来使用特定的验证方式。在配置验证的时候,通常设置默认的验证架构。当没有指定验证架构的时候,就会使用默认架构进行处理。

        还可以

        注册的验证模式,最终变成 AuthenticationScheme,注册到依赖注入服务中。

        在 GitHub 中查看 AuthenticationScheme 源码

        各种验证架构被保存到一个 IAuthenticationSchemeProvider 中。

        在 GitHub 中查看 IAuthenticationSchemeProvider 源码

        最终的使用是通过 IAuthenticationHandlerProvider 来实现的,通过一个验证模式的字符串名称,可以取得所对应的验证控制器。

        在 GitHub 中查看 IAuthenticationHandlerProvider 源码

        它的默认实现是 AuthenticationHandlerProvider,源码并不复杂。

        在 GitHub 中查看 AuthenticationHandlerProvider 源码

        验证中间件的处理就没有那么复杂了。

        找到默认的验证模式,使用默认验证模式的名称取得对应的验证处理器,如果验证成功的话,把当前请求用户的主体放到当前请求上下文的 User 上。

        里面还有一段特别的代码,用来找出哪些验证处理器实现了 IAuthenticationHandlerProvider,并依次调用它们,看看是否需要提取终止请求处理过程。

        在 GitHub 中查看 AuthenticationMiddle 源码

asp.net core依赖注入原理

       依赖注入(DI)是现代软件开发中常用的一种设计模式,用于解耦代码和简化组件之间的依赖关系。在.NET Core框架中,依赖注入主要通过两个NuGet包实现:Microsoft.Extensions.DependencyInjection.Abstractions和Microsoft.Extensions.DependencyInjection。这些包提供了抽象接口和服务提供容器的默认实现,为开发者提供了灵活且高效的服务注入机制。

       .NET Core的依赖注入概念由四个核心组件构成:IServiceCollection,保存IServiceDescriptor实例的列表;IServiceProvider,提供服务并管理服务生命周期的php悬赏源码容器;IServiceDescriptor,描述服务,包括服务类型、实现类型、生命周期以及创建服务实现的工厂;ServiceLifetime,定义服务的生命周期,分为三种:Singleton、Scoped和Transient。

       在.NET Core中,依赖注入由这些主要类型及其相关方法形成。IServiceCollection用于收集服务描述,而IServiceProvider则作为服务提供容器,负责创建和管理服务。在使用依赖注入时,服务被注册到IServiceCollection中,并指定其生命周期,如Singleton、Scoped或Transient。

       单例模式下,服务的生命周期与根容器保持一致,即服务将随根容器的销毁而销毁。Scoped模式下,每个请求创建一个新的Scope,生成一个独立的服务提供容器,服务实例随Scope的销毁而销毁。而Transient模式下的服务则随用随取,用完即销毁。

       在ASP.NET Core应用中,Scoped服务实例的生命周期管理可能需要额外关注。尽管Scoped意图在每个请求中创建和释放服务实例,但在实际应用中,Scoped服务实例可能变成Singleton,导致资源泄露,如数据库连接。为避免此类问题,可以在创建服务提供容器时进行验证,确保服务实例的生命周期与期望一致。

       解决服务范围验证的常见方法是在创建服务提供容器时传入一个布尔参数,指示依赖注入容器在注入服务时检查Scoped服务是否被错误使用。错误使用通常包括使用根服务提供容器创建Scoped服务实例或让Singleton服务依赖Scoped服务实例,导致服务生命周期错误。

       为了与第三方依赖注入框架集成,如Unity或Autofac,开发者可以使用IServiceProviderFactory接口,实现从IServiceCollection到IServiceProvider的转换。具体操作包括创建一个针对特定框架的ContainerBuilder对象,先使用IServiceCollection创建ContainerBuilder,再构建IServiceProvider,从而实现服务注册与依赖注入的整合。

       NET Core的承载系统(Hosting system)提供了一个框架,允许开发者构建和部署后台长时间运行的服务。在承载系统中,服务的注册通常通过IServiceCollection进行,而依赖注入容器通过IServiceProvider实现。若需整合第三方依赖注入框架,开发者需解决从IServiceCollection到IServiceProvider的适配问题,通过设置ContainerBuilder对象并使用IServiceProviderFactory接口来实现。

理解ASP.NET Core-文件服务器(File Server)

       提供静态文件

       静态文件默认存储在Web根目录中,路径为项目根目录下的wwwroot文件夹,位于{ Content Root}/wwwroot。

       通过调用Host.CreateDefaultBuilder方法,可使用UseContentRoot方法将程序当前工作目录设置为项目根目录。

       或通过UseWebRoot扩展方法自定义静态文件路径,尽管这通常不需要。

       在wwwroot文件夹下创建config.json文件,内容随意。

       确保wwwroot下的文件属性设置为“如果较新则复制”或“始终复制”。

       使用UseStaticFiles扩展方法注册StaticFileMiddleware。

       访问/stefanprodan...,并了解到这是一个专门设计用于管理 Web API 或 MVC 应用程序请求速率的解决方案。官方介绍指出,此组件包含两个中间件:IpRateLimitMiddleware 和 ClientRateLimitMiddleware,这些中间件允许您根据 IP 地址或客户端 ID 设置多个限流规则,例如每秒、分钟内的调用次数限制。更令人满意的是,组件的配置相对简单,可以直接在应用程序设置中进行调整,而无需重新编译代码。官方还提供了一个简单的例子,说明如何在 appsettings.json 文件中进行配置。

       组件的使用过程相当灵活,只需要在 ASP.NET Core 配置中定义规则即可。这使得在不重新编译代码的情况下修改限流规则成为可能。组件提供了两种主要模式:IP 地址和 ClientID。我选择使用 IP 地址模式,因为 ClientID 可能需要额外的实现(如用户ID),而这可以通过请求头自定义。接下来,我简要介绍了组件的配置步骤,包括如何在程序中注册配置服务、注册相关服务、解析配置代码,以及如何配置 Redis 存储方式以确保稳定运行。

       在实现限流功能时,我首先关注如何实现对特定 IP 地址或 IP 地址段的限制。组件提供了多种存储方式供选择,我选择了内存存储作为示例,但考虑到项目稳定性的需求,我最终决定使用 Redis 作为存储介质。配置 Redis 操作的具体代码展示了如何设置 Redis 连接参数,以及如何注入 IRateLimitConfiguration 服务,这通常意味着中间件将使用此服务。

       为了使限流功能与项目集成,我需要在 Program.cs 中注册服务并添加中间件。将 UseRateLimit 方法添加到 UseStaticFiles 之后,以避免页面静态文件对限流规则的误触发。在 appsettings.json 文件中,我配置了具体的限流规则,包括全局限流和针对特定路径或 HTTP 方法的限流规则。我自定义了被限流时的提示信息,以提供更友好的用户体验。

       最后,附上我的配置文件,展示了对添加工单、登录、注册接口进行限流的配置。这些配置不仅限制了特定功能的访问频率,还自定义了当用户尝试超过预设次数时的提示信息。通过这种方式,项目能够有效地管理资源使用,避免过度请求对服务器造成的压力。