欢迎大家阅读《朝夕Net社区技术专刊》第6期
我们致力于.NetCore的推广和落地,为更好的帮助大家学习,方便分享干货,特创此刊!很高兴你能成为忠实读者,文末福利不要错过哦!
前言:
本部分文档将详细给大家介绍CoreWebApi的Authorize鉴权授权;为什么要鉴权授权呢?如果没有启用身份认证,那么任何匿名用户只要知道了我们服务的url,就能随意访问我们的服务接口,从而访问或修改数据库。所以在各种系统开发中授权是必备的;今天这里就给大家说说授权的事儿。
01
PART
传统方式的授权
请看下图,在传统授权中,因为Http请求是没有状态的,http请求第一次请求和第二次请求是没有关系的,所有在传统的授权方式里面使用的是Session+Cookes;Session使用的较多;思路:客户端(浏览器)第一次请求服务器的时候,服务器针对于当前这个浏览器生成一个Session:Key-value形式,SessionId:Session值;客户端来登录获取权限的时候,服务器然后在响应请求的时候,把SessionId返回给客户端浏览器;浏览器把SessionId保存在cookies中,再次去请求服务器的时候带上这个SessionId的标识,然后服务器就可以识别到,这是上次某某某浏览器来访问过我,登陆过,这个SessionId是我服务器颁发的,就通过了权限认证了。
基于Session cookies的权限校验是比较传统的,也是最常见的,不过基于Session、Cookies的权限校验,存在一些尴尬事儿。
因为Session是存储在服务器的,在一些大型分布集群服务器中,Session共享的问题不太好解决(当然这里不是说不能解决),比方说有A/B/C/D四个服务器集群,那么登录时候如果是A服务器生成的Session,那么B服务器是不能用的;需要做Session共享,成本相对来说较高;
像大家在使用一些系统的时候,常常会见到一些像QQ、微信、淘宝账号 这类第三方账号登录,如果使用Cookies和Session来实现,成本很高;
02
PART
基于令牌的鉴权授权——Basic授权
在Asp.NetWebApi中可以使用Basic授权;Basic授权是基于令牌的,在登录的时候,服务器给颁发一个tiket(这里可以理解成一个钥匙),然后你去访问Api的时候,把这个tiket给带上,就可以通过校验;Basic认证实现起来非常简单;下面我把代码贴在这里供大家参考。
图1
注:就是在用户登录的时候通过在请求登录的时候传递的参数生成一个Tiket;使用PostMan调用如图2所示;
图2
那么有tiket了,在调用Api的时候,就需要验证这个tiket了,怎么验证呢?Richard老师这里是使用Asp.NetMVC中的Filter---AuthorizeAttribute来实现的。
图3
定义个Api:GetUserInfo.
在没有标记任何Filter的时候,通过Ajax请求Api;结果可以正常拿到,请看图4、图5
图4
图5
那标记特性以后呢?请看图6;图7
图6
图7
请求结果拿不到,因为在请求WebApi的时候没有把tiket带上。请看图8、图9、图10;
图8
图9
图10
现在可以正常调用Api获取到数据;那么Basic的流程如下:
1. 获取tiket;
2. 在调用Api的时候,把tiket带上;通过验证tiket的来达到授权的效果;
03
PART
基于令牌的鉴权授权——Jwt鉴权授权
Jwt鉴权:Json Web Token是在.NetCore中最主流的鉴权授权方式,这里Richard老师准备给大家详细解读Jwt鉴权授权的核心思路;请看图1
图1
图1为jwt鉴权授权的架构图,图1中分别有四个角色,客户端-User,鉴权中心AuthorziationServer,资源提供-Api, 第三方Api-Third-Party。
根据图中的流程:
请求鉴权中心AuthorziationServer(根据账号密码到鉴权中心登录),获取Token
去请求资源Api 或者第三方Api Third-Party 的时候带上token,就可以获取数据;
小伙伴儿在看到这个图以后,可能会觉得奇怪,资源Api并没有和鉴权中心AuthorizatinServer发生交互,是怎么验证权限的呢?这其实是Jwt鉴权的一大特点;
那是怎么鉴权的呢?下面就给大家解惑一下:
其实鉴权中心在生成Token, Api在通过Token验证权限的时候,这二者或有一个非对称可逆加密解密的过程;
1. 鉴权中心兜儿里有一个私钥,用来加密;私钥是私密的,只有鉴权中心知道;
2. 资源Api或者第三方Api Thrid-Party兜儿里有一个和鉴权中的那个私钥对应的解密公钥,就是鉴权中心私钥加密,资源Api,公钥解密;公钥是公开的;谁都是知道的;
【这里涉及到有非对称加密解密的知识,如果对这一块的内容不是很理解的,可以联系QQ: 1432568536获取关于加密解密的内容】
那么鉴权中心和资源Api之间是怎么完成的呢?
在鉴权中心,登录以后,生成的Token是通过私钥加密的,这里就只有公钥能解开。
在请求Api的时候,资源Api有公钥,那么资源Api就去尝试解密,如果能解开,说明这个Token确实是来自于鉴权中心,那OK,那资源Api就通过校验,正常返回数据;否则就表示没有权限。
下面给大家介绍一下这个Token的内容结构:如图2,是一段标准的Token内容;一共分为三段。
图2
第一段:头信息,红色部分,图3所示,表示加密算法:HS256,类型是jwt鉴权;
图3
第二段:图4所示:紫色部分,表示有效载荷,也就是在这个Token里面可以携带一些信息,有Token标准的信息内容,也可以自定义加一些内容。
图4
第三段:签名
签名Signature
=HMACSHA256( base64UrlEncode(头信息) + "." + base64UrlEncode(有效载荷信息), 公钥)
通过HMACSHA256 算法加密 +.+ Base64位的头信息+.+Base64位的有效载荷信息+.+公钥;三段内容通过点连接起来形成一个完整的Token 令牌。
那Token里的内容能修改吗?不能修改,如果修改过了,内容解密后,跟真实内容就不一样了;下面就基于Jwt在Core环境下做一个实现。
如果图1中所示,得有一个鉴权中心专门用来颁发Token;
图5
这里使用到了一个JwtService: 如图6jwtService 实现;
1.需要Nuget引入程序包:Microsoft.IdentityModel.Tokens
Nuget引入程序包:System.IdentityModel.Tokens.Jwt
图6
2.需要在配置文件里配置:如图7所示
图7
【这部分的代码可以联系朝夕教育助教老师获取:QQ: 1432568536】如此鉴权中心就OK了;那Api部分呢?下面将继续说说Api如何基于Jwt授权。
1. CoreWebApi需要在Startup 下的ConfigureServices中增加如下代码:
如图8所示
图8
2.在Startup中的Configure中指定使用授权;如图9所示;
图9
3. 在资源Api中标记特性;如图10所示。
图10
测试:
第一步:命令启动WebApi: dotnet Zhaoxi.Core.WebApi.dll --urls="http://*:8004" -- ip="127.0.0.1" --port= 8004
如图11所示:
图11
第二步:PostMan 请求Api;图12所示,表示没有授权;所以需要授权,那怎么授权呢?需要启动鉴权中心,获取令牌Toke
图12
第三步:命令启动鉴权中心:dotnet Zhaoxi.Core.AuthenticationCenter.dll --urls="http://*:8001" -- ip="127.0.0.1" --port= 8001
如图13所示
图13
第四步:PostMan请求获取Token;如图14所示:
图14
第五步:图14获取到了Toke, 就可以带上token 请求Api,正常获取数据,图15,图16所示。
图15
图16
以上就是整套的Jwt权限验证过程,使用的是Jwt鉴权授权。