既然选择了远方,便只顾风雨兼程 __ HANS许

在上篇文章,我们讲了JWT在ASP.NET Core的实现,基于中间件来实现。这种方式有个缺点,就是所有的URL,要嘛需要验证,要嘛不需要验证,没有办法各取所需,因为我们某个API与另一个API的验证方式不一样。这就引导出“基于自定义策略形式下的验证了”。

ASP.NET Core 的Authorization实现

我们使用Core自带的Authorization(认证与授权)来实现。大家可以先看下微软官方的策略授权

  1. 微软官方例子:
    1.1 定义策略

    1. internal class MinimumAgeAuthorizeAttribute : AuthorizeAttribute 

    2. { 

    3. const string POLICY_PREFIX = "MinimumAge"; 

    4. public MinimumAgeAuthorizeAttribute(int age) => Age = age; 

    5. // Get or set the Age property by manipulating the underlying Policy property 

    6. public int Age 

    7. { 

    8. get 

    9. { 

    10. if (int.TryParse(Policy.Substring(POLICY_PREFIX.Length), out var age)) 

    11. { 

    12. return age; 

    13. } 

    14. return default(int); 

    15. } 

    16. set 

    17. { 

    18. Policy = $"{POLICY_PREFIX}{value.ToString()}"; 

    19. } 

    20. } 

    21. } 

    1.2 使用策略

    1. [MinimumAgeAuthorize(10)] 

    2. public IActionResult RequiresMinimumAge10() 

    这样在执行RequiresMinimumAge10会先执行MinimumAgeAuthorize策略,很像MVC的Attribute特性,
    但内部又不像,在这边就不多做解释了,微软的Core官方文档讲的很清楚。大家去看下就清楚了。

  2. JWT的自定义策略形式的实现
    2.1 了解IAuthorizationRequirement
    IAuthorizationRequirement表示授权要求,用户可以继承这个接口,实现自己认证与授权的要求,比如上面的片段代码,它就继承该接口,并有个字段Age,也就是这个策略有年龄的要求,这个要求可以带到我们后面验证的方法里面。我们往下看。

    2.2 继承IAuthorizationRequirement
    所以我们实现了JwtAuthorizeBaseRequiremente该接口,并继承IAuthorizationRequirement,可以看到我们的要求是一个叫validatePayLoad的委托函数,委托函数的入参是字典,JWT,字典便是上篇文章说的JWT的负载部分了。而返回参数是bool,便代表我们自定义的策略验证JWT是否成功。IJwtAuthorizRequiremente继承了IAuthorizationRequirement

    1. public class JwtAuthorizeBaseRequiremente : IJwtAuthorizRequiremente 

    2. { 

    3. protected internal Func<Dictionary<string, string>, JsonWebTokenSetting, bool> validatePayLoad = (a, b) => 

    4. { 

    5. return true; 

    6. }; 


    7. public virtual IJwtAuthorizRequiremente SetValidateFunc(Func<Dictionary<string, string>, JsonWebTokenSetting, bool> func) 


    8. { 

    9. this.validatePayLoad = func ?? this.validatePayLoad; 

    10. return this; 

    11. } 

    12. } 

    2.3 了解AuthorizationHandler
    AuthorizationHandler为特定需求类型调用的授权处理程序的基类。也就是说我们处理策略是会到这个基类来处理,并且判断是否认证成功,也就是授权成功。

    2.4 继承AuthorizationHandler
    JwtAuthorizeHandler继承AuthorizationHandler并实现泛型JwtAuthorizeBaseRequiremente的定义,这样子我们的自定义的策略委托验证函数就会传递到这个处理类。我们需要重写HandleRequirementAsync来自定已处理。可以看到,最终我们还是调用上篇文章所讲的验证函数_jsonWebTokenValidate.Validate,大家不清楚可以去看上篇文章。而requirement.validatePayLoad便是我们稍后再外面自定义的验证函数了。

    1. public class JwtAuthorizeHandler : AuthorizationHandler<JwtAuthorizeBaseRequiremente> 

    2. { 

    3. private readonly JsonWebTokenSetting _setting; 

    4. private readonly IJsonWebTokenValidate _jsonWebTokenValidate; 


    5. public JwtAuthorizeHandler(IOptions<JsonWebTokenSetting> setting, IJsonWebTokenValidate jsonWebTokenValidate) 

    6. { 

    7. this._setting = setting.Value; 

    8. this._jsonWebTokenValidate = jsonWebTokenValidate; 

    9. } 


    10. /// <summary> 

    11. /// 验证JWT 

    12. /// </summary> 

    13. /// <param name="context"></param> 

    14. /// <param name="requirement"></param> 

    15. /// <returns></returns> 

    16. protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, JwtAuthorizeBaseRequiremente requirement) 

    17. { 

    18. var httpContext = (context.Resource as AuthorizationFilterContext).HttpContext; 


    19. var result = httpContext.Request.Headers.TryGetValue("Authorization", out StringValues authStr); 

    20. if (!result || string.IsNullOrEmpty(authStr.ToString())) 

    21. { 

    22. throw new UnauthorizedAccessException("未授权,请传递Header头的Authorization参数。"); 

    23. } 

    24. result = result && _jsonWebTokenValidate.Validate(authStr.ToString().Substring("Bearer ".Length).Trim(), _setting, requirement.validatePayLoad); 

    25. if (!result) 

    26. { 

    27. throw new UnauthorizedAccessException("验证失败,请查看传递的参数是否正确或是否有权限访问该地址。"); 

    28. } 

    29. context.Succeed(requirement); 

    30. return Task.CompletedTask; 

    31. } 

    32. } 

    2.5 怎么使用呢?

    • 我们需要在Startup.cs文件进行注册服务。其中CommonAuthorize继承JwtAuthorizeBaseRequiremente,并将自定义的策略方法,传递进去。其中common是策略名称。可以多个定义策略

      1. public void ConfigureServices(IServiceCollection services) 

      2. { 

      3. services.AddJwt(Configuration); 

      4. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 

      5. services.AddAuthorization(option => 

      6. { 

      7. #region 自定义验证策略 可以一直自定义策略 

      8. option.AddPolicy("common", policy => policy.Requirements.Add(new CommonAuthorize(). 

      9. SetValidateFunc((playLoad, sertting) => 

      10. { 

      11. //每个策略自定义验证函数,playLoad为带过来的参数字典,setting为失效时间与秘钥 

      12. return true; 

      13. }))); 

      14. #endregion 自定义验证策略 

      15. }).AddAuthentication(option => 

      16. { 

      17. option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; 

      18. }); 

      19. }  

    • 接着我们在想要的Controller或者Action的头部使用[Authorize(Policy = "common")],这样每次进到相对应的Controller或者Action,会先进行策略验证,而我们这边验证的便是JWT了。

总结一下,我们在这篇文章是基于上篇文章的,所以JWT的生成与验证我们就不讲了。两篇文章讲了JWT的验证,两种方式有好有坏,大家可以根据自己的模式进行选择。

1.使用管道的方式,感觉方便点,清晰点
2. 使用自定义策略的方式,效率稍微高一点,毕竟不是所有的请求都会进行是否可以匿名访问运算和建立管道的消耗,只有加入Authorize属性的Controller和Action的才会进入

最后附上源码,或者直接到我的GitHub上看看。后面要是有时间,可以讲下IdentityServer4的OAuth2的授权与认证。

ASP.NET Core的JWT的实现(自定义策略形式验证).md的更多相关文章

  1. ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统

    为什么使用 Jwt 最近,移动开发的劲头越来越足,学校搞的各种比赛都需要用手机 APP 来撑场面,所以,作为写后端的,很有必要改进一下以往的基于 Session 的身份认证方式了,理由如下: 移动端经 ...

  2. ASP.NET Core 基于JWT的认证(二)

    ASP.NET Core 基于JWT的认证(二) 上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用 ...

  3. asp.net core 集成JWT(一)

    [什么是JWT] JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案. JWT的官网地址:https://jwt.io/ 通俗地来讲,JWT是能代表用户身份的令牌,可以使用JWT ...

  4. asp.net core 集成JWT(二)token的强制失效,基于策略模式细化api权限

    [前言] 上一篇我们介绍了什么是JWT,以及如何在asp.net core api项目中集成JWT权限认证.传送门:https://www.cnblogs.com/7tiny/p/11012035.h ...

  5. ASP.NET Core 基于JWT的认证(一)

    ASP.NET Core 基于JWT的认证(一) Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计 ...

  6. Asp.Net Core基于JWT认证的数据接口网关Demo

    近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对 ...

  7. ASP.NET Core 使用 JWT 自定义角色/策略授权需要实现的接口

    目录 ① 存储角色/用户所能访问的 API ② 实现 IAuthorizationRequirement 接口 ③ 实现 TokenValidationParameters ④ 生成 Token ⑤ ...

  8. ASP.NET Core的JWT的实现(中间件).md

    既然选择了远方,便只顾风雨兼程 __ HANS许 JWT(JSON Web Token) ASP.NET Core 的Middleware实现 引言:挺久没更新了,之前做了Vue的系列,后面想做做服务 ...

  9. Asp.Net Core 入门(三) —— 自定义中间件

    上一篇我们讲了Startup文件,其中着重介绍了中间件,现在我们就来自定义我们自己的中间件吧. 中间件通常封装在一个类中,并使用扩展方法进行暴露.它需要拥有一个类型为RequestDelegate的成 ...

随机推荐

  1. itest 开源测试管理项目中封装的下拉列表小组件:实现下拉列表使用者前后端0行代码

    导读: 主要从4个方面来阐述,1:背景:2:思路:3:代码实现:4:使用 一:封装背景       像easy ui 之类的纯前端组件,也有下拉列表组件,但是使用的时候,每个下拉列表,要配一个URL ...

  2. netcore使用 jenkins + supervisor 实现standalone下多副本自动化发布

    上一篇我们用jenkins做了一个简单的自动化发布,在shell中采用的是 BUILD_ID=dontKillMe nohup dotnet xxx.dll &  这种简单的后台承载,如果你的 ...

  3. C# -Asp.Net.SignalR.Core之Hub

    前言 程序员的进步是需要环境的,良好的团队环境,良好的开发环境,会让人进步的更加快速. 所以,我认为,如果一个程序员,在2019年还在用Visual Studio 2005开发,那么,他,大概率,不会 ...

  4. 在阿里云服务器windows server2012r iis上部署.net网站

    先说一堆废话:之前在阿里云上租了一个服务器,也配置了相关的环境,然后准备把自己手上的一个小网站挂上去,就按照我的上篇博客记载的方法把发布好的网站发布到服务器的iis上,结果发布之后死活访问不了,始终显 ...

  5. 教程:关于如何通过Maven仓库安装Spire系列的 Java产品

    Spire系列库中已发布的Java产品目前有三个,即Spire.PDF for Java.Spire.Presentation for Java.Spire.Barcode for Java.使用该J ...

  6. swagger Failed to load Api definition 的问题

    这个问题是由于Tomcat乱码问题导致的,修改server.xml文件的编码格式修改成UTF-8

  7. 为什么会有Comparable与Comparator接口? 引入策略模式

    目录 引入 Comparable接口的来龙去脉 引入Comparator接口 什么是策略模式? 使用了策略模式有什么好处? 引入 大家先考虑一个场景, 有一个整形数组, 我们希望通过调用一个工具类的排 ...

  8. 自学WEB前端到什么程度才能就业

    做过多年web前端从业者,回答下这个问题 首先,这个问题主要问:自学web前端技术,如果才能找到一份web前端的工作.按照现在的招聘标准来看,无论你去哪个公司面试,你只需要满足他们公司的需求就可以. ...

  9. 给WEB初学者一些有效率的建议

    因为IT互联网发展的非常迅速,而web前端这块很火,目前工资水平给的很高,在市场上也是非常的稀缺人才,现在各个行业转行做web前端的很多,今天给大家一些建议,希望新手少走点弯路吧! 建议一:有一个比较 ...

  10. Dynamics 365 CE命令栏按钮点击后刷新表单页面方法

    微软动态CRM专家罗勇 ,回复326或者20190428可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! Dynamics 365 Customer Engagement ...