ASP.NET Core的JWT的实现(中间件).md
既然选择了远方,便只顾风雨兼程 __ hans许
引言:挺久没更新了,之前做了vue的系列,后面想做做服务端的系列,上下衔接,我们就讲讲webapi(网络应用程序接口),接口免不了用户认证,所以接下来我们的主题系列文章便是“基于asp.net core的用户认证”,分为市面上流行的jwt(json webtoken)与oauth2(开放授权)
jwt(json web token)
-
什么叫jwt
json web token(jwt)是目前最流行的跨域身份验证解决方案。一般来说,互联网用户认证是这样子的。
1、用户向服务器发送用户名和密码。
2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
3、服务器向用户返回一个 session_id,写入用户的 cookie。
4、用户随后的每一次请求,都会通过 cookie,将 session_id 传回服务器。
5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。服务器需要保存session,做持久化,这种模式没有分布式架构,无法支持横向扩展,如果真的要的话就必须采用分布式缓存来进行管理seesion。那jwt相反,它保存的是在客户端,每次请求都将jwt代入服务器,进行签名,权限验证。jwt由客户端请求,服务端生成,客户端保存,服务端验证。
-
jwt的原理与格式
-
原理
在上面,我们也讲过了,简单的来说,我们将服务器需要验证我们的条件(账户,密码等等),发给服务器,服务器认证通过,生成一个json对象返回给我们,例如下面。当然,为了防止被篡改,所以我们会将对象加密,再次请求服务器,需要将jwt放在请求头部,传递给服务器,来判断权限等等。- {
- "姓名": "张三",
- "角色": "管理员",
- "到期时间": "2018年7月1日0点0分"
- }
-
格式
- 实际格式
- eyjhbgcioijiuzi1niisinr5cci6ikpxvcj9.
- eyjbijoiqufbqsisikiioijcqkjciiwiqyi6ikndq0milcj1zxiioij4dwh1ywxliiwib3blbmlkijointe1njezmtm1mtyzmjeilcjmzii6imrmc2rzzgzzzgzzzhmilcjuymyioje1ntiymte4njasimv4cci6mtu1mjixmzy2mh0.
- 16m57ynnicgith25dwphqkpyuiq42bvmzv6libo7kdg
它是一个很长的字符串,中间用点(.)分隔成三个部分。注意,jwt内部是没有换行的,这里只是为了便于展示,将它写成了几行。jwt 的三个部分依次如下。
- header(头部)
- payload(负载)
- signature(签名)
简单讲下,
header
描述加密算法与token类型,payload
描述的是实际需要传递的数据,如失效时间,签发人等等,signature
描述的是一段对于前面两部部分的签名,当然秘钥只有服务器才知道。
-
简单的介绍下jwt,更多的话,可以这边看看。我们着重讲下实现。
asp.net core 的middleware实现
-
创建jwt
首先我们要先创建token,毕竟这个是最重要的。core自带jwt帮助类,所以我们按照帮助类的意思来写个方法创建token。- public string createjsonwebtoken(dictionary<string, string> payload)
- {
- if (string.isnullorwhitespace(setting.securitykey))
- {
- throw new argumentnullexception("jsonwebtokensetting.securitykey",
- "securitykey为null或空字符串。请在\"appsettings.json\"配置\"jsonwebtoken\"节点及其子节点\"securitykey\"");
- }
- var now = datetime.utcnow;
- // specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.
- // you can add other claims here, if you want:
- var claims = new list<claim>();
- foreach (var key in payload.keys)
- {
- var tempclaim = new claim(key, payload[key]?.tostring());
- claims.add(tempclaim);
- }
- // create the jwt and write it to a string
- var jwt = new jwtsecuritytoken(
- issuer: null,
- audience: null,
- claims: claims,
- notbefore: now,
- expires: now.add(timespan.fromminutes(setting.expiresminute)),
- signingcredentials: new signingcredentials(new symmetricsecuritykey(encoding.ascii.getbytes(setting.securitykey)), securityalgorithms.hmacsha256));
- var encodedjwt = new jwtsecuritytokenhandler().writetoken(jwt);
- return encodedjwt;
- }
从方法我们看到,我们传入的是负载这个片段,而失效时间与秘钥我们是放在了
appsettings.json
来进行配置的。使用di来获取配置文件中的节点值。 -
编写中间件
我们都知道,中间件是core的管道模型组成部分,所以我们在中间件做验证,来判断每次请求用户是有有权限是有该webapi或者其他api。- 中间件
- public jwtcustomerauthorizemiddleware(requestdelegate next, ioptions<jsonwebtokensetting> options, ijsonwebtokenvalidate jsonwebtokenvalidate, func<dictionary<string, string>, jsonwebtokensetting, bool> validatepayload, list<string> anonymouspathlist)
- {
- this._next = next;
- this._setting = options.value;
- this._jsonwebtokenvalidate = jsonwebtokenvalidate;
- this._validatepayload = validatepayload;
- this._anonymouspathlist = anonymouspathlist;
- }
- public async task invoke(httpcontext context)
- {
- //jsonwebtokenvalidate
- //若是路径可以匿名访问,直接跳过
- if (_anonymouspathlist.contains(context.request.path.value))
- {
- //还未验证
- await _next(context);
- return;
- }
- var result = context.request.headers.trygetvalue("authorization", out stringvalues authstr);
- if (!result || string.isnullorempty(authstr.tostring()))
- {
- throw new unauthorizedaccessexception("未授权,请传递header头的authorization参数。");
- }
- //进行验证与自定义验证
- result = _jsonwebtokenvalidate.validate(authstr.tostring().substring("bearer ".length).trim()
- , _setting, _validatepayload);
- if (!result)
- {
- throw new unauthorizedaccessexception("验证失败,请查看传递的参数是否正确或是否有权限访问该地址。");
- }
- await _next(context);
- }
从代码来看,
anonymouspathlist
是url路径,若是在这个list
内的url,便可直接跳过验证,
接着将authstr
token代入验证函数,validatepayload
却是我们自代入的委托函数,用于服务器自定义验证。- 验证
验证方法,我只是做了签名验证与时间验证。并没有定得死死的,让用户*度的去进行验证。- public bool validate(string encodejwt, jsonwebtokensetting setting, func<dictionary<string, string>, jsonwebtokensetting, bool> validatepayload)
- {
- if (string.isnullorwhitespace(setting.securitykey))
- {
- throw new argumentnullexception("jsonwebtokensetting.securitykey",
赞 (0)打赏 微信扫一扫相关文章:
-
-
如下所示: # coding=utf-8 # 用来处理数字,大于上限的数字置零 f = open("/home/... [阅读全文]
-
使用Python向C语言的链接库传递数组、结构体、指针类型的数据
使用python向c语言的链接库传递数组、结构体、指针类型的数据 由于最近的项目频繁使用python调用同事的c语言代码,在调用过... [阅读全文] -
Tomcat的安装和配置 Tomcat 是在SUN公司的JSWDK(JavaServer Web DevelopmentKit)的基础上发展而来的一... [阅读全文]
-
前景概要 对于现在的Java开发基本上可以说成是spring开发,spring全家桶可以说是把整个Java web安排的明明白白的。正因为使用的很多... [阅读全文]
-
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
- 中间件
上一篇: 求最小环的几种姿势
下一篇: Django的时区设置问题
推荐阅读
-
Asp.Net Core中基于Session的身份验证的实现
-
asp.net core集成JWT的步骤记录
-
在ASP.NET Core 中发送邮件的实现方法(必看篇)
-
ASP.NET Core基于微软微服务eShopOnContainer事件总线EventBus的实现
-
ASP.NET Core中自定义路由约束的实现
-
详解ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁
-
ASP.NET Core2实现静默获取微信公众号的用户OpenId
-
ASP.NET Core 2.2 : 二十六. 应用JWT进行用户认证及Token的刷新
-
Asp.Net Core中基于Session的身份验证的实现
-
在ASP.NET Core 中发送邮件的实现方法(必看篇)
发表评论