Authorization — (5) 授权与认证的实现对比

概念对比

Authentication Authorization
全局选项 AuthenticationOptions AuthorizationOptions
模式/策略 AuthenticationScheme:
   - Name,
   - HandlerType
AuthorizationPolicy:
   - AuthenticationSchemes,
   - Requirements
模式/策略Provider IAuthenticationSchemeProvider
AuthenticationSchemeProvider
IAuthorizationPolicyProvider
DefaultAuthorizationPolicyProvider
具体模式/策略细节 AuthenticationSchemeOptions IRequirement
具体模式/策略Handler IAuthenticationHandler
AuthenticationHandler<SomeSchemeOptions>
IAuthorizationHandler
Authorization<SomeRequirement>
HandlerProvider IAuthenticationHandlerProvider
AuthenticationHandlerProvider
IAuthorizationHandlerProvider
DefaultAuthorizationHandlerProvider
服务 IAuthenticationService
AuthenticationService
IAuthorizationService
DefaultAuthorizationService

配置过程对比

针对Authentication的配置过程,如:

1
2
3
4
5
6
7
8
services.AddAuthentication(options =>{
...
}) // 返回一个AuthenticationBuilder
.AddScheme<SomeSchemeOptions,SomeAuthenticationHandler>(name,opts=>{ ... })
.AddCookie(name, opts =>{ ... })
.AddJwtBearer(name, opts =>{ ... }
...
;

其实是在配置全局的AuthenticationOptions。他们都会在内部调用AddSchemeHelper<TOptions,THandler>(name,configurer) 会配置全局的AuthenticationOptions,向其中添加<schemeName>-<handlerType>的映射关系。

类似的,Authorization的配置过程其实就是配置AuthorizationOptions的过程,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
services.AddAuthorization(options =>
{
options.AddPolicy("policy1", policyBuilder => {
policyBuilder.Requirements.Add(new MyRequirement());
// ...
} );
options.AddPolicy("policy2", policyBuilder => {
policyBuilder.RequireAssertion(ctx =>{
... return true;
... return false;
});
});
... // other policies
});

和可以添加多种AuthenticationScheme一样,我们可以为AuthorizationOptions添加多个Policy。不过这里每个Policy中可以有多个RequirementsAuthenticationSchemes。此外,和Authentication.AddScheme<TOptions,THandler>(...)不同,可以观察到这里的配置过程对某个Requirement对应的AuthorizationHandler一无所知,所以也无法把特定的AuthorizationHandler自动注册为服务——这也是开发者需要手工注册AuthorizationHandler服务的根本原因。