🚀 优质资源分享 🚀
学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
🧡 Python实战微信订餐小程序 🧡 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
💛Python量化交易实战💛 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
在上一篇 聊聊 asp.net core 认证和授权 中我们提到了认证和授权的基本概念,以及认证和授权的关系及他们之间的协同工作流程,在这篇文章中,我将通过分析asp.net core 3.1 授权流程的源码给大家介绍asp.net core 框架里面授权流程的具体实现逻辑,本文并非讲解具体的实战应用,建议在使用过asp.net core 授权框架后在来阅读本文收货会更多。
一、授权流程用到的主要的几个接口及类
- IAuthorizationService,默认实现类: DefaultAuthorizationService,该类主要职责就是遍历所有注入到容器的实现了IAuthorizationHandler接口的服务,并调用其HandleAsync方法来进行授权检查,也就是说该类的主要职责就是检查授权策略(AuthorizationPolicy)是否校验通过,校验通过则授权成功,否则授权失败。
- IAuthorizationPolicyProvider,默认实现类:DefaultAuthorizationPolicyProvider,负责根据策略名称提供授权策略,以及提供默认授权策略等,内部就是从AuthorizationOptions内部的策略字典(Dictionary)中直接获取。
- IAuthorizationHandlerProvider,默认实现类:DefaultAuthorizationHandlerProvider,用于获取已经注册到容器中的所有实现了IAuthorizationHandler的授权服务,所有授权服务是通过构造函数依赖注入实现的(IEnumerable作为构造函数入参)
- IAuthorizationHandler,默认实现类:PassThroughAuthorizationHandler,该类是AddAuthorization的时候默认注册的授权处理程序(实现IAuthorizationHandler接口),用于遍历授权策略中包含的所有的实现了IAuthorizationHandler的Requirement类,并调用其HandleAsync方法进行检查Requirement授权是否成功,这里的Requirement类是指实现了AuthorizationHandler抽象基类的Requirement类。
- IAuthorizationEvaluator,默认实现类:DefaultAuthorizationEvaluator,执行授权流程,并对授权检查结果进行检查,如果是授权失败,并且未认证则返回401,如果是授权失败,但认证通过,则返回403
- IAuthorizationHandlerContextFactory,默认实现类:DefaultAuthorizationHandlerContextFactory
- AuthorizationMiddleware,负责对请求进行授权检查的中间件.
- AuthorizationOptions类,内部维护了一个策略字典(Dictionary)用于存储所有注册的策略,key为策略名称,value为具体的策略(AuthorizationPolicy)
- AuthorizationPolicy类,策略的具体表示,主要包含 AuthenticationSchemes 和 Requirements属性,AuthenticationSchemes 表示执行该策略时采用什么认证方案进行身分认证, Requirements 表示该策略要验证的Requirement列表
- AuthorizationPolicyBuilder类,该类主要是用于构建AuthorizationPolicy类,也就是用于构建具体策略的类,通过该类,可以指定该授权策略需要采用什么认证方案进行认证,以及授权检查时需要满足那些Requirement。
二、授权服务注册流程
首先找到 PolicyServiceCollectionExtensions 类,这个扩展方法类,对IServiceCollection接口进行了扩展,因此我们可以在Startup.cs 的ConfigureService方法中直接
services.AddAuthorization来注册 授权相关服务。
// Microsoft.Extensions.DependencyInjection.PolicyServiceCollectionExtensions
using System;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
public static class PolicyServiceCollectionExtensions
{
public static IServiceCollection AddAuthorizationPolicyEvaluator(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException("services");
}
services.TryAddSingleton();
services.TryAdd(ServiceDescriptor.Transient());
return services;
}
//当不想在应用程序中注册授权策略时,直接调用此方法即可。
public static IServiceCollection AddAuthorization(this IServiceCollection services)
{
return services.AddAuthorization(null);
}
//当需要在应用程序中注册特定的授权策略时,调用这个方法,configure为Action类型的委托方法,入参为AuthorizationOptions 授权配置类,
//可通过该类的AddPolicy方法来进行授权策略的注册。
public static IServiceCollection AddAuthorization(this IServiceCollection services, Action configure)
{
if (services == null)
{
throw new ArgumentNullException("services");
}
services.AddAuthorizationCore(configure);
services.AddAuthorizationPolicyEvaluator();
return services;
}
}
可以看到,内部调用了AddAuthorizationCore方法,这个扩展方法定义在:AuthorizationServiceCollectionExtensions 类
// Microsoft.Extensions.DependencyInjection.AuthorizationServiceCollectionExtensions
using System;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
public static class AuthorizationServiceCollectionExtensions
{
public static IServiceCollection AddAuthorizationCore(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException("services");
}
//以下这些服务便是上文中介绍的授权流程用到的主要服务类,及具体的默认实现类。
services.TryAdd(ServiceDescriptor.Transient());
services.TryAdd(ServiceDescriptor.Transient());
services.TryAdd(ServiceDescriptor.Transient());
services.TryAdd(ServiceDescriptor.Transient());
services.TryAdd(ServiceDescriptor.Transient());
services.TryAddEnumerable(ServiceDescriptor.Transient());
return services;
}
public static IServiceCollection AddAuthorizationCore(this IServiceCollection services, Action configure)
{
if (services == null)
{
throw new ArgumentNullException("services");
}
//这里的configure便是我们应用程序传入的委托回调方法,用于向AuthorizationOptions类添加授权策略。
if (configure != null)
{
services.Configure(configure);
}
return services.AddAuthorizationCore();
}
}
下面这个是应用注册授权策略的常规流程的一个例子:
public void ConfigureServices(IServiceCollection services)
{
//添加授权相关服务。
services.AddAuthorizat