net6授权认证源码详解(三)

授权

接下来跟着源码来一起学习授权相关知识。

一般的service注入服务方式有如下:

builder.Services.AddAuthorization(option =>
{
    //增加授权策略
    option.AddPolicy("Api1", builder =>
    {
        builder.RequireAuthenticatedUser();
        builder.RequireClaim("scope", "api1");
        builder.AddRequirements(new CustomAuthorizationRequirement("Policy01");
    });
});

这里来一起查看AddAuthorization做了什么事?

源码AddAuthorization路径(aspnetcore/src/Security/Authorization/Policy/src/PolicyServiceCollectionExtensions.cs)。

AddAuthorizationCore注册了AuthorizationOptions配置项内容,此内容会在之后的DefaultAuthorizationPolicyProvider类GetPolicyAsync调用其AuthorizationOptions自身的GetPolicyTask(policyName)方法获取以下AddPolicy配置内容(通过PolicyMap)。

AddAuthorization内的option()=>{},是对AuthorizationOptions进行的配置。看一下具体配置内容。

 大致看代码,就是通过AuthorizationPolicyBuilder配置完成后,build()生成AuthorizationPolicy保存在本身的字典内。

这里讲解具体配置方法具体含义

/*
在类型为List<IAuthorizationRequirement>()的Requirements中
新增"拒绝匿名访问"即为DenyAnonymousAuthorizationRequirement。

DenyAnonymousAuthorizationRequirement的操作HandleRequirementAsync
方法中判断当前用户身份是否存在以及是否认证,如果是,
则在AuthorizationHandlerContext上下文内设置_succeedCalled=true,
_pendingRequirements.Remove(requirement);//移除当前DenyAnonymousAuthorizationRequirement

*/

builder.RequireAuthenticatedUser();

——————————————————————————————————————————————————————————————————————————————————————
/*
在类型为List<IAuthorizationRequirement>()的Requirements中
新增new ClaimsAuthorizationRequirement("scope", "api1")。


ClaimsAuthorizationRequirement的操作HandleRequirementAsync
方法中判断当前用户身份是否存在给定的ClaimType(此处为"scope"),如果是,
则在AuthorizationHandlerContext上下文内设置_succeedCalled=true,
_pendingRequirements.Remove(requirement);//移除当前ClaimsAuthorizationRequirement
*/

builder.RequireClaim("scope", "api1");

——————————————————————————————————————————————————————————————————————————————————————
/*
向Requirements添加自定义IAuthorizationRequirement内容,
此处自定义类为CustomAuthorizationRequirement
*/


builder.AddRequirements(new CustomAuthorizationRequirement("Policy01");

——————————————————————————————————————————————————————————————————————————————————————

AddAuthorizationCore()方法注册一些服务项。

 AddAuthorizationPolicyEvaluator()同样注册了一些服务项。

 至此,AddAuthorization()的内容都了解了,无非是注册了一些服务项,没有额外的其他。

接下来看授权使用,一般的写法如下所示

app.UseAuthorization()

UseAuthorization,路径(aspnetcore/src/Security/Authorization/Policy/src/AuthorizationAppBuilderExtensions.cs)

查看关键代码,AuthorizationMiddleware。

1、context.GetEndPoint()获取EndPointRoutingMiddleware中间选择的终结点,通过endPoint.MetaData获取对应action方法上标注的所有特性(其中AuthorizeAttribute继承自IAuthorizeData)。

2、AuthorizationPolicy.CombineAsync整合IAuthorizeData,AuthorizationPolicy和IAuthorizationRequirementData的数据内容生成完整AuthorizationPolicy(整合内容:Requirements和AuthenticationSchemes,其中Requirements中包含角色roles)。

3、IPolicyEvaluator.AuthenticateAsync(policy, context)验证认证。

4、IPolicyEvaluator.AuthorizeAsync(policy, authenticateResult!, context, resource)验证授权。

 其中,_authorization为DefaultAuthorizationService,涉及到调用AuthorizationServiceExtensions(路径:aspnetcore/src/Security/Authorization/Core/src/AuthorizationServiceExtensions.cs)

 认证核心代码为DefaultAuthorizationService(路径:aspnetcore/src/Security/Authorization/Core/src/DefaultAuthorizationService.cs):

①_contextFactory.CreateContext,获取认证处理上下文。

②_handlers.GetHandlersAsync,最终获取到PassThroughAuthorizationHandler。

 ③handler.HandleAsync,获取所有的Requirements,调用他们自身的HandleAsync方法进行处理。此处自带或者自定义的Requirement都必须继承AuthorizationHandler<>泛型方法,重写HandleRequirementAsync进行逻辑处理。

 重写范例如下DenyAnonymousAuthorizationRequirement:

 自此,net6授权过程的全部源代码讲完了,核心处理就在AuthorizationOption中配置的Requirement中,一张图结束本节内容。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值