17

跟我一起学.NetCore之WebApi接口裸奔有风险(Jwt)

 3 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwNTMxMzg1MA%3D%3D&%3Bmid=2654080731&%3Bidx=2&%3Bsn=4c8924dd81b7e8864133a66b6aee5c4b
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

撸码需谨慎,裸奔有风险。经常在一些技术交流群中了解到,还有很多小伙伴的项目中Api接口没有做任何安全机制验证,直接就裸奔了,对于一些临时项目或是个人小项目还好,其余的话,建议小伙伴们酌情考虑都加上,毕竟接口安全这事可大可小。

通常会采用session、cookie、jwt、ids4等方式进行接口安全认证或授权,这里就先拿jwt说事,ids4知识点比较多,后续单独整理整理;对于session和cookie的方式就留给小伙伴们研究吧,因为最近接触或是和朋友聊到的项目中,使用的不多,所以就不单独拿出来细说了。

正文

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。---官网翻译

主要用于系统中授权认证,使得在数据交换过程中通过Token方式进行校验,相对比较安全;而Token包含三部分,每部分用点( . )进行拼接,内容结构为: Header.Payload.Signature

  • Header(头)

    一个Json对象,通过Base64URL算法将其转换为一个字符串。里面有两个属性,alg和typ分别代表签名算法和生成token的类型。

  • Payload(负载)

    一个Json对象,通过Base64URL算法将其转换为一个字符串。里面默认有一些官方定义的信息,也可以将自定义信息加入到其中,但是由于不是加密的,强烈不介意将敏感信息放在其中。默认属性大概如下:

iss (issuer):签发人

exp (expiration time):过期时间

sub (subject):主题

aud (audience):接受方

nbf (Not Before):生效时间

iat (Issued At):签发时间

jti (JWT ID):唯一编号

  • Signature(签名)

    这个是对前两部分的内容进行签名,需要一个秘钥,再通过Header中指定的签名算法生成签名。比如指定算法为HMACSHA256时,生成的签名为:

收,理论知识就先提及这么多,如果需要详细了解的,可以进管网(https://jwt.io/introduction)瞅瞅,英文版怕怕?别啊,翻译工具那么多,应该难不倒小伙伴。接下来就通过代码演示方式说说jwt使用方式及涉及到的相关知识点吧

这里还是在上一篇文章的例子上进行举例演示( 跟我一起学.NetCore之Swagger让前后端不再烦恼及界面自定义 ),不是偷懒,而是利用Swagger方便测试,另外就是针对认证对Swagger进行一个小知识点的扩展。

2mAjU3.png!mobile

以上Swagger内容不是必须,如果小伙伴不想用Swagger进行测试,直接使用类似于Postman的工具也是可以的,测试方式不冲突,所以小伙伴们别跑,咱们继续往下看↓↓↓

使用组件的经典三步走:安装包->注册组件->注册中间件;jwt集成使用如下:

zqYRfef.png!mobile

2qMVJrY.png!mobile

通过以上简单三步操作,已经将Jwt集成到项目中,接下来开始用它来保护我们的Api接口:

BBzInyM.png!mobile

如上,通过简单的在接口上增加[Authorize]特性就能保护起来啦,现在只能带“身份证”才能玩了,那系统中得有一个颁发"身份证"的地方,供系统识别验证,一般都会将其放在登录接口的地方,当用户验证成功之后,就生成对应的Token给客户端,客户端拿着这个Token就可以当“身份证”来调用接口啦,看如下代码:

EbQRRr.png!mobile

这个错误应该是刚开始经常遇到的,必须要求密钥是大于等于16个字符,否则就会失败。修改 长度如下:

BRfqmqa.png!mobile

然后运行,重新登录获取Token,如下图:

E3qIbea.png!mobile

可以看到,上面代码中的公共信息部分应该提取到公共配置信息中,不然要改几个地方,所以在程序开发过程中,小伙伴么尽量不要硬编码,不然就等于给自己找维护工作。

Token已经生成了,那怎么用?现在Swagger不支持输入Token,可以使用postman类似的工具进行接口测试,如下:

ZFfeM3j.png!mobile

输入Token,成功获取信息:

UzaI7v7.png!mobile

Token的使用本质其实是在Header中增加了一个Authorization头,如下图:

73IZVj.png!mobile

Authorization中的值为Bearer+' '+Token,中间一定要有一个空格。同理,前端调用API接口的时候也是在请求头中增加Authorization即可。

拿到Token,就可以访问受保护的API了,现在应该了解一下生成的Token是否和刚开始说的理论一样,同时可以通过jwt官网进行解析查看具体内容:

通过官网解析看看内容:

InyY7zA.png!mobile

通过上面得知,没有经过业务加密的Token,是可以进行解析的,所以不建议把一些敏感信息放在Payload中。但是对于认证来说是安全,因为校验签名是需要 的,而 是存在服务器端,一般人肯定是不知道的。

对于Token的过期,有一个点,即过期滑动时间,如果不设置,默认是五分钟,即当设置Token有效期到期时,不会马上失效,而是再过五分钟才失效,如下例:

FNBFZjy.png!mobile

过了几分钟后还是没有过期,如下:

2YziMnR.png!mobile

过六分之后,再访问,发现Token才失效,如果觉得过期滑动时间不满足需求,可以进行设置,如下:

n2uae2B.png!mobile

这里运行效果就不截图了,小伙伴试试吧!!! 这里关于Jwt的集成先说这么多,肯定是没有说完的,还有权限验证那块,单独整理一篇说吧,内容也不少。

Swagger小扩展

既然都用到Swagger,肯定是希望在Swagger上直接测试,来来来,继续往下看看↓↓↓

在注册Swagger组件时进行相关配置:

UZvURbJ.png!mobile

运行结果如下:

FZJJNvZ.png!mobile

点击小锁,弹出框可进行Token输入:

IZRzUbm.png!mobile

输入Token授权之后就可以调用保护的接口,可以很方便的进行测试,这里就不截图演示了,小伙伴们动手试试吧。

附加知识点:

由于SecurityRequirementsOperationFilter默认将securitySchemaName 设置为"oauth2",所以在Swagger中加入描述的时候需要指定第一个参数为 " oauth2" ,源码如下:

jumyeiz.png!mobile

也可以换成其他方式,参照实现的方式2,两种方式差不多,如下图:

bEbM7fZ.png!mobile

注意点:

  • 生成Token时的密钥大于或等于16个字符;

  • 生成的Token中默认不加密,敏感信息不要放入其中,如果有需要,可以将Token进行加密;

  • Token传输如果是外网,建议用Https,防止中途被拦截;

  • Token防止泄露,可以将有效期设置短一点;

总结

关于权限的验证单独再整理一篇分享,这里就先到这吧;旅游或回家的小伙伴们应该都回到自己的住处了吧,好好休息休息,又要开始撸码啦。

一个被程序搞丑的帅小伙,关注"Code综艺圈",识别关注跟我一起学~~~

uEv6ZfA.png!mobile

撸文不易,莫要白瞟,三连走起~~~~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK