手机版

如何在ASP.NET core 2.1中使用jwt从原理到掌握(2)

时间:2021-08-29 来源:互联网 编辑:宝哥软件园 浏览:

在aspnet core中,自定义jwt管道验证

有了上一节的内容做基础,也很轻松。关键点在于中间件,只需要把测试类中上一级的自定义验证放到中间件中。

但是需要注意的是,中间件的位置非常重要,只有它后面的管道会受到影响;

那我们先构建一个定制的中间件类吧:(这里我就不说中间件的细节了,大家可以参考官网和其他博文)

///summary////自定义授权中间件////summary公共类jwtcustomemauthorize中间件{ private readonly request delegate next;public jwtcustomemauthorize中间件(请求委托next,字符串secret,liststring匿名路径列表){# region设置密钥if(!字符串。IsNullOrEmpty(secret)){ token context . securitykey=secret;} # endregion this.next=nextUserContext。allowanonymouspath list . AddRange(anonymoupath list);}公共异步任务调用(HttpContext上下文,UserContext userContext,ioptionjwtoption option container){ if(user context。IsAllowAnonymous(上下文。请求.路径)){等待下一个(上下文);返回;} var option=optionContainer。价值;#区域身份验证,并设置用户Ruser值var result=context . request . headers . try getvalue(' authorization ',out string values auth str);if(!结果| |字符串。is ullrempty(authstr。tostring())){抛出新的未授权访问异常(' unauthorized ');}结果=令牌上下文。验证(authStr。ToString()。子字符串('承载者'。长度)。Trim(),payLoad={ var success=true//可以添加一些自定义验证。有关用法,请参考测试用例。//验证aud是否包含并等于rober account success=success payload[' aud ']?ToString()==选项。观众;如果(成功){//设置Ruse值,将用户信息放入payLoad中(获取jwt时将当前用户存储在payLoad的ruser Key中)//如果用户信息较多,建议放入缓存中,并存储缓存的Key值usercontext。try init(LoAd[' ruser ']?ToString());}返回成功;});if(!结果){抛出新的未授权访问异常(' unauthorized ');} # endregion #区域权限验证if(!用户context . authorize(context . request . path)){抛出新的未授权访问异常(' unauthorized ');} #endregion等待下一个(上下文);}}上面的中间件中有一个UserContext线程。该类主要管理当前用户信息和权限,其他信息暂时忽略;让我们先来看看这个中间件的验证过程:

中间件主要验证访问路径,当然你也可以验证其他信息,比如(控制器名、动作名等。)

检查当前网址是否可以匿名访问,如果可以,直接通过,无需验证;如果不是可以匿名访问的路径,那么继续获取当前http头携带的jwt(存储在头的Authorization中);使用上一节中的令牌上下文进行必要的验证和自定义复杂验证;获取当前访问用户信息,我们把用户的基本信息放在payLoad['ruser']中,请看代码到目前为止是如何操作的,全部都是认证,说明你是身份人;下一步是做权限验证。仅仅因为你是一个有身份的人,并不意味着你是一个随便到处拜访的人;权限验证必须识别您可以访问的URL或操作。我们将权限验证放在用户上下文中。授权方法(这里不深入解释如何操作。基本原理是从数据库或缓存中获取当前用户对应的权限列表,即URL列表,并进行比较);定制中间件使用jwt验证这些内容是否感觉清晰、简单、具体;

中间已经完成了,接下来就用吧。我们在启动时将以下代码添加到Configure方法中

应用程序.UseMiddlewareJwtCustomerAuthorizeMiddleware(配置[' jwtoptions : securitykey '],新list string(){ '/API/values/getjwt ','/' });当然上面可匿名访问的全球资源定位器(统一资源定位符)也可以定义在appsetting.json文件中,可以自行尝试

如何通过自定义策略形式实现自定义智威汤逊广告公司验证

创建自定义策略的详细介绍可以参考官网,这里就不详细介绍,

首先我们上代码,创建自定义策略非常重要的两个类,如下:

公共类CommonAuthorizeHandler : authorizationhandlercommanaauthorize {///summary///常用自定义验证策略,模仿自定义中间件JwtCustomerauthorizeMiddleware的验证范围////summary////param name=' context '/param///param name=' requisition '/param///returns/returns受保护的覆盖任务句柄要求同步(AuthorizationHandlerContext上下文,通用授权申请){ var httpContext=(上下文.资源为AuthorizationFilterContext).HttpContextvar user context=httpContext .请求服务。获取服务(类型为(用户上下文))作为用户上下文;var jwtOption=(httpContext .RequestServices。GetService(类型为(IOptionsJwtOption))作为IOptionsJwtOption ).价值;#地区身份验证,并设置用户诡计值var result=httpContext .请求。标题。trygetvalue(' Authorization ',out字符串值authStr);if(!结果||字符串IsNullOrEmpty(authStr .ToString())){ 0返回任务。完成任务;}结果=令牌上下文。验证(authStr .ToString().子字符串('承载者。长度)。Trim(),CLaSS={ var success=true//可以添加一些自定义验证,用法参照测试用例//验证是否包含奥德并等于roberAudience success=success LoAd[' aud ']?ToString()==jwtOption .观众;如果(成功){ //设置诡计值,把用户信息放在有效载荷中,(在获取智威汤逊广告公司的时候把当前用户存放在有效载荷的诡计键中) //如果用户信息比较多,建议放在缓存中有效载荷中存放缓存的钥匙值用户上下文.TryInit(LoAd[' ruser ']?ToString());}返回成功;});if(!结果){返回任务。完成任务;} #endregion #region权限验证if(!用户上下文.授权(httpContext .请求。路径)){返回任务。完成任务;} #endregion上下文。成功(要求);返回任务。完成任务;} }公共类CommonAuthorize:授权要求{ }其中两个重要的类是哪两个呢?他们的作用又是什么呢?

1、公共授权:授权要求,至于取什么名字,自己定义,但必须继承IAuthorizationRequirement,这类主要是承载一些初始化值,让后传递到处理者中去,给验证做逻辑运算提供一些可靠的信息;我这里是空的;自己根据自身情况自己定义适当的属性作为初始数据的承载容器;

2、CommonAuthorizeHandler : authorizationhandlercommanaauthorize这个是重点,承载了验证的逻辑运算需要重写覆盖任务句柄要求同步方法,所有的逻辑都在该方法中,他的主要逻辑和上面的自定义中间件很相似,只少了上面的第一步;验证流程如下:

获取当前http头携带的jwt(存储在头的Authorization中);使用上一节中的令牌上下文进行必要的验证和自定义复杂验证;获取当前访问用户信息,我们把用户的基本信息放在payLoad['ruser ',请看代码到目前为止是如何操作的,全部都是认证,说明你是身份人;下一步是做权限验证。仅仅因为你是一个有身份的人,并不意味着你是一个随便到处拜访的人;权限验证必须识别您可以访问的URL或操作。我们将权限验证放在用户上下文中。授权方法(这里不深入解释如何操作。基本原理是从数据库或缓存中获取当前用户对应的权限列表,即URL列表,并进行比较);语境。成功(要求);是的,验证成功。如果没有这个,默认情况下验证会失败。因为用户上下文负责权限验证,所以流程不会感到混乱,并且可以重用。至于那种形式的验证,很容易切换。3.是不是很简单,几乎和用户自定义管道验证的代码一样?

如何使用自定义定义策略?

1.将以下代码添加到启动类的ConfigureServices中:

服务。addauthorization(选项={# region自定义身份验证策略选项。addpolicy ('common ',policy=policy。要求。添加(新的common authorize());#endregion })。添加身份验证(选项={ option。default scheme=JwtBearerDefaults。AuthenticationScheme}).AddJwtBearer(option={ if(!字符串。IsNullOrEmpty(config[' jwtoptions : securitykey ']){ token context . securitykey=config[' jwtoptions : securitykey '];}//设置要验证的项目选项。tokenvalidation参数=新的tokenvalidation参数{issuersigningkey=新的对称安全密钥(编码。utf 8 . getbytes(token context . security key))//获取security key };});//自定义策略IOC添加服务。addsingletioniauthorizationhandler,commonuthorizehandler();以上代码主要分为3个部分

1.添加以上自定义策略并命名;

2.设置密钥,这是上一节中生成jwt的密钥。必须相同,否则签名不正确

3.注入一个上面建立的重要类CommonAuthorizeHandler,如上面的代码所示

2.添加应用。使用身份验证()在启动类中进行配置;

3.向要验证的控制器或操作添加[授权(策略='公共')]属性,如下图所示:

到目前为止,您可以使用自定义策略验证;

使用管道和自定义策略进行验证有什么区别?

它们在效果上都是一样的,只是略有不同

使用管道很方便,明确使用定制策略效率会高一点。毕竟不是所有的请求都会消耗匿名访问和管道建立,只有添加了Authorize属性的Controller和Action才会进入;当然,这个损失可以忽略,看你自己的喜好;至于你喜欢哪个,用哪个,性能可以忽略;

无论哪种方式使用jwt作为身份和权限验证都不是很简单,这里的关键是提取权限验证的逻辑,让代码越来越清晰;

至于Authorize的属性形式,还有很多其他的策略,比如用户、声明、角色等。可在官网https://docs . Microsoft.com/zh-cn/aspnet/core/security/authorization/?view=aspnetcore-2.0

下一章将解释用户、声明和角色的验证,以及如何在自定义验证中实现这些,这样每个人都可以和他有一个清晰的比较

摘要

以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。

版权声明:如何在ASP.NET core 2.1中使用jwt从原理到掌握(2)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。