当前位置: 代码迷 >> 综合 >> 【朝夕技术专刊】Core3.1WebApi_Filter-Authorize详解
  详细解决方案

【朝夕技术专刊】Core3.1WebApi_Filter-Authorize详解

热度:46   发布时间:2024-01-12 10:14:28.0

欢迎大家阅读《朝夕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。

根据图中的流程:

  1.  请求鉴权中心AuthorziationServer(根据账号密码到鉴权中心登录),获取Token

  2. 去请求资源Api 或者第三方Api Third-Party 的时候带上token,就可以获取数据;

小伙伴儿在看到这个图以后,可能会觉得奇怪,资源Api并没有和鉴权中心AuthorizatinServer发生交互,是怎么验证权限的呢?这其实是Jwt鉴权的一大特点;

那是怎么鉴权的呢?下面就给大家解惑一下:

其实鉴权中心在生成Token,  Api在通过Token验证权限的时候,这二者或有一个非对称可逆加密解密的过程;

1.    鉴权中心兜儿里有一个私钥,用来加密;私钥是私密的,只有鉴权中心知道;

2.    资源Api或者第三方Api Thrid-Party兜儿里有一个和鉴权中的那个私钥对应的解密公钥,就是鉴权中心私钥加密,资源Api,公钥解密;公钥是公开的;谁都是知道的;

【这里涉及到有非对称加密解密的知识,如果对这一块的内容不是很理解的,可以联系QQ: 1432568536获取关于加密解密的内容】

 

那么鉴权中心和资源Api之间是怎么完成的呢?

  1.  在鉴权中心,登录以后,生成的Token是通过私钥加密的,这里就只有公钥能解开。

  2.  在请求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. 1.需要Nuget引入程序包:Microsoft.IdentityModel.Tokens

              Nuget引入程序包:System.IdentityModel.Tokens.Jwt

图6

  1. 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鉴权授权。