ASP.NET Core的JWT的实现(自定义策略形式验证).md
既然选择了远方,便只顾风雨兼程 __ HANS许
在上篇文章,我们讲了JWT在ASP.NET Core的实现,基于中间件来实现。这种方式有个缺点,就是所有的URL,要嘛需要验证,要嘛不需要验证,没有办法各取所需,因为我们某个API与另一个API的验证方式不一样。这就引导出“基于自定义策略形式下的验证了”。
ASP.NET Core 的Authorization实现
我们使用Core自带的Authorization(认证与授权)来实现。大家可以先看下微软官方的策略授权
微软官方例子:
1.1 定义策略- internal class MinimumAgeAuthorizeAttribute : AuthorizeAttribute
- {
- const string POLICY_PREFIX = "MinimumAge";
- public MinimumAgeAuthorizeAttribute(int age) => Age = age;
- // Get or set the Age property by manipulating the underlying Policy property
- public int Age
- {
- get
- {
- if (int.TryParse(Policy.Substring(POLICY_PREFIX.Length), out var age))
- {
- return age;
- }
- return default(int);
- }
- set
- {
- Policy = $"{POLICY_PREFIX}{value.ToString()}";
- }
- }
- }
1.2 使用策略
- [MinimumAgeAuthorize(10)]
- public IActionResult RequiresMinimumAge10()
这样在执行
RequiresMinimumAge10会先执行MinimumAgeAuthorize策略,很像MVC的Attribute特性,
但内部又不像,在这边就不多做解释了,微软的Core官方文档讲的很清楚。大家去看下就清楚了。- internal class MinimumAgeAuthorizeAttribute : AuthorizeAttribute
JWT的自定义策略形式的实现
2.1 了解IAuthorizationRequirement
IAuthorizationRequirement表示授权要求,用户可以继承这个接口,实现自己认证与授权的要求,比如上面的片段代码,它就继承该接口,并有个字段Age,也就是这个策略有年龄的要求,这个要求可以带到我们后面验证的方法里面。我们往下看。2.2 继承
IAuthorizationRequirement
所以我们实现了JwtAuthorizeBaseRequiremente该接口,并继承IAuthorizationRequirement,可以看到我们的要求是一个叫validatePayLoad的委托函数,委托函数的入参是字典,JWT,字典便是上篇文章说的JWT的负载部分了。而返回参数是bool,便代表我们自定义的策略验证JWT是否成功。IJwtAuthorizRequiremente继承了IAuthorizationRequirement- public class JwtAuthorizeBaseRequiremente : IJwtAuthorizRequiremente
- {
- protected internal Func<Dictionary<string, string>, JsonWebTokenSetting, bool> validatePayLoad = (a, b) =>
- {
- return true;
- };
- public virtual IJwtAuthorizRequiremente SetValidateFunc(Func<Dictionary<string, string>, JsonWebTokenSetting, bool> func)
- {
- this.validatePayLoad = func ?? this.validatePayLoad;
- return this;
- }
- }
2.3 了解
AuthorizationHandler
AuthorizationHandler为特定需求类型调用的授权处理程序的基类。也就是说我们处理策略是会到这个基类来处理,并且判断是否认证成功,也就是授权成功。2.4 继承
AuthorizationHandler
JwtAuthorizeHandler继承AuthorizationHandler并实现泛型JwtAuthorizeBaseRequiremente的定义,这样子我们的自定义的策略委托验证函数就会传递到这个处理类。我们需要重写HandleRequirementAsync来自定已处理。可以看到,最终我们还是调用上篇文章所讲的验证函数_jsonWebTokenValidate.Validate,大家不清楚可以去看上篇文章。而requirement.validatePayLoad便是我们稍后再外面自定义的验证函数了。- public class JwtAuthorizeHandler : AuthorizationHandler<JwtAuthorizeBaseRequiremente>
- {
- private readonly JsonWebTokenSetting _setting;
- private readonly IJsonWebTokenValidate _jsonWebTokenValidate;
- public JwtAuthorizeHandler(IOptions<JsonWebTokenSetting> setting, IJsonWebTokenValidate jsonWebTokenValidate)
- {
- this._setting = setting.Value;
- this._jsonWebTokenValidate = jsonWebTokenValidate;
- }
- /// <summary>
- /// 验证JWT
- /// </summary>
- /// <param name="context"></param>
- /// <param name="requirement"></param>
- /// <returns></returns>
- protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, JwtAuthorizeBaseRequiremente requirement)
- {
- var httpContext = (context.Resource as AuthorizationFilterContext).HttpContext;
- var result = httpContext.Request.Headers.TryGetValue("Authorization", out StringValues authStr);
- if (!result || string.IsNullOrEmpty(authStr.ToString()))
- {
- throw new UnauthorizedAccessException("未授权,请传递Header头的Authorization参数。");
- }
- result = result && _jsonWebTokenValidate.Validate(authStr.ToString().Substring("Bearer ".Length).Trim(), _setting, requirement.validatePayLoad);
- if (!result)
- {
- throw new UnauthorizedAccessException("验证失败,请查看传递的参数是否正确或是否有权限访问该地址。");
- }
- context.Succeed(requirement);
- return Task.CompletedTask;
- }
- }
2.5 怎么使用呢?
我们需要在
Startup.cs文件进行注册服务。其中CommonAuthorize继承JwtAuthorizeBaseRequiremente,并将自定义的策略方法,传递进去。其中common是策略名称。可以多个定义策略- public void ConfigureServices(IServiceCollection services)
- {
- services.AddJwt(Configuration);
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
- services.AddAuthorization(option =>
- {
- #region 自定义验证策略 可以一直自定义策略
- option.AddPolicy("common", policy => policy.Requirements.Add(new CommonAuthorize().
- SetValidateFunc((playLoad, sertting) =>
- {
- //每个策略自定义验证函数,playLoad为带过来的参数字典,setting为失效时间与秘钥
- return true;
- })));
- #endregion 自定义验证策略
- }).AddAuthentication(option =>
- {
- option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
- });
- }
- public void ConfigureServices(IServiceCollection services)
接着我们在想要的
Controller或者Action的头部使用[Authorize(Policy = "common")],这样每次进到相对应的Controller或者Action,会先进行策略验证,而我们这边验证的便是JWT了。
- public class JwtAuthorizeBaseRequiremente : IJwtAuthorizRequiremente
总结一下,我们在这篇文章是基于上篇文章的,所以JWT的生成与验证我们就不讲了。两篇文章讲了JWT的验证,两种方式有好有坏,大家可以根据自己的模式进行选择。
1.使用管道的方式,感觉方便点,清晰点
2. 使用自定义策略的方式,效率稍微高一点,毕竟不是所有的请求都会进行是否可以匿名访问运算和建立管道的消耗,只有加入Authorize属性的Controller和Action的才会进入
最后附上源码,或者直接到我的GitHub上看看。后面要是有时间,可以讲下IdentityServer4的OAuth2的授权与认证。
ASP.NET Core的JWT的实现(自定义策略形式验证).md的更多相关文章
- ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统
为什么使用 Jwt 最近,移动开发的劲头越来越足,学校搞的各种比赛都需要用手机 APP 来撑场面,所以,作为写后端的,很有必要改进一下以往的基于 Session 的身份认证方式了,理由如下: 移动端经 ...
- ASP.NET Core 基于JWT的认证(二)
ASP.NET Core 基于JWT的认证(二) 上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用 ...
- asp.net core 集成JWT(一)
[什么是JWT] JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案. JWT的官网地址:https://jwt.io/ 通俗地来讲,JWT是能代表用户身份的令牌,可以使用JWT ...
- asp.net core 集成JWT(二)token的强制失效,基于策略模式细化api权限
[前言] 上一篇我们介绍了什么是JWT,以及如何在asp.net core api项目中集成JWT权限认证.传送门:https://www.cnblogs.com/7tiny/p/11012035.h ...
- ASP.NET Core 基于JWT的认证(一)
ASP.NET Core 基于JWT的认证(一) Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计 ...
- Asp.Net Core基于JWT认证的数据接口网关Demo
近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对 ...
- ASP.NET Core 使用 JWT 自定义角色/策略授权需要实现的接口
目录 ① 存储角色/用户所能访问的 API ② 实现 IAuthorizationRequirement 接口 ③ 实现 TokenValidationParameters ④ 生成 Token ⑤ ...
- ASP.NET Core的JWT的实现(中间件).md
既然选择了远方,便只顾风雨兼程 __ HANS许 JWT(JSON Web Token) ASP.NET Core 的Middleware实现 引言:挺久没更新了,之前做了Vue的系列,后面想做做服务 ...
- Asp.Net Core 入门(三) —— 自定义中间件
上一篇我们讲了Startup文件,其中着重介绍了中间件,现在我们就来自定义我们自己的中间件吧. 中间件通常封装在一个类中,并使用扩展方法进行暴露.它需要拥有一个类型为RequestDelegate的成 ...
随机推荐
- ASP.NET Core 实战:构建带有版本控制的 API 接口
一.前言 在上一篇的文章中,主要是搭建了我们的开发环境,同时创建了我们的项目模板框架.在整个前后端分离的项目中,后端的 API 接口至关重要,它是前端与后端之间进行沟通的媒介,如何构建一个 “好用” ...
- 为自己搭建一个分布式 IM(即时通讯) 系统
前言 大家新年快乐! 新的一年第一篇技术文章希望开个好头,所以元旦三天我也没怎么闲着,希望给大家带来一篇比较感兴趣的干货内容. 老读者应该还记得我在去年国庆节前分享过一篇<设计一个百万级的消息推 ...
- HTTPS和TCP协议三次握手设计
1. 我们的TCP 三次握手大概是长这样 2.那么为什么 TCP 要采取三次握手,而不是两次或其他 首先我们要知道握手的目的: 为了保证通讯双方建立的连接是可靠的. 同时,为了保证性能,握手的次数要求 ...
- 为什么VUE注册组件命名时不能用大写的?
这段时间一直在弄vue,当然也遇到很多问题,这里就来跟大家分享一些注册自定义模板组件的心得 首先"VUE注册组件命名时不能用大写"其实这句话是不对的,但我们很多人开始都觉得是对的, ...
- 补习系列(18)-springboot H2 迷你数据库
目录 关于 H2 一.H2 用作本地数据库 1. 引入依赖: 2. 配置文件 3. 样例数据 二.H2 用于单元测试 1. 依赖包 2. 测试配置 3. 测试代码 小结 关于 H2 H2 数据库是一个 ...
- Cenots7下安装运行.NET Core、MicroSoft SQL Server 2019 preview 的基础实践
一:概要 适应人群:.Net初学者.想了解.Net Core在Linux系统中的运行环境搭建者.初次且想在linux上应用.Net Core开发应用程序者: 基础技能:了解.NET基础开发技能者.有一 ...
- ERP小金刚Pro专业大比拼: Dynamics,NetSuite和Odoo
前言 在过去的15年中,新技术推动了大大小企业的重新思考他们的流程管理涉及不断变化的业务所创造的新动态景观.实施ERP是许多企业为帮助组织而采取的措施并优化他们开展业务的方式.然而,市场上目前有许多商 ...
- Error:Execution failed for task ':app:processDebugManifest'.
Attribute meta-data#android.support.VERSION@value value=(26.1.0) from AndroidManifest.xml:28:13-35 i ...
- Android之Material Dialogs详解
文章大纲 一.什么是Material Dialogs二.Material Dialogs实战三.项目源码下载 一.什么是Material Dialogs Material Dialogs是一个 ...
- Android路由框架-ARouter详解
文章大纲 一.页面路由基本介绍1.什么是页面路由2.为什么要使用页面路由二.页面路由框架ARouter介绍1.常用功能介绍2.常见应用场景三.源码下载四.参考文章 一.页面路由基本介绍 1.什么是 ...