Spring Cloud Gateway + Jwt + Oauth2 实现网关的鉴权操作

Spring Cloud Gateway + Jwt + Oauth2 实现网关的鉴权操作,第1张

随着我们的微服务越来越多,如果每个微服务都要自己去实现一套鉴权操作,那么这么操作比较冗余,因此我们可以把鉴权操作统一放到网关去做,如果微服务自己有额外的鉴权处理,可以在自己的微服务中处理。

1、在网关层完成url层面的鉴权操作。

2、将解析后的jwt token当做请求头传递到下游服务中。

3、整合Spring Security Oauth2 Resource Server

1、搭建一个可用的认证服务器, 可以参考之前的文章

2、知道Spring Security Oauth2 Resource Server资源服务器如何使用, 可以参考之前的文章

自定义授权管理器,判断用户是否有权限访问

此处我们简单判断

1、放行所有的 OPTION 请求。

2、判断某个请求(url)用户是否有权限访问。

3、所有不存在的请求(url)直接无权限访问。

1、 客户端 gateway 在认证服务器拥有的权限为 useruserInfo

3、在网关层面,findAllUsers 需要的权限为 useruserInfo ,正好 gateway 这个客户端有这个权限,所以可以访问。

演示GIF

https://giteecom/huan1993/spring-cloud-alibaba-parent/tree/master/gateway-oauth2

  一个服务器和客户端知道一个公钥和一个私钥;只有服务器和客户端知道私钥,但每个人都知道公钥。。。但不关心别人所知道的。

  一个客户端生成一个唯一的HMAC(哈希)表示它到服务器的请求。通过把请求数据(参数和值或XML/JSON或任何它计划发送的数据)以及请求数据的散列blob和私钥结合来实现。

  客户端随后将这个HASH以及所有它将要发送的参数和值一并发给服务器。

  服务器接到请求,并使用与客户端相同的方式重新生成自己独有的基于提交值的HMAC(哈希)。

  然后,服务器比较这两个HMAC,如果相同,服务器就信任这个客户端并执行请求。

  

  这似乎很直截了当。最初让你困惑的是,你以为原始请求是经过加密传送的,但实际上,HMAC方法所做的一切只是使用只有客户端和服务器才知道的私钥将参数生成为一些独特的校验和(哈希)。

  随后,客户端将这个校验和及原始参数和值发给服务器,然后服务器复核校验和(哈希)以确定它接受客户端所发的请求。

  因为根据假设,只有在客户端和服务器知道私钥,我们假设如果他们的哈希匹配,那么它们会互相信任,以至服务器随即正常处理这个请求。

  你知道在现实中,这就相当于某人过来对你说:“Jimmy让我告诉你把钱给Johnny”,但你不知道这个人是谁,所以你要伸出手去试探他,看看他是否知道这个秘密握手。

  

  如果三次握手证明无误,则通讯继续进行,否则中断通讯。

  

1、玉符科技的还可以,现在不少都用这个产品,操作不难,市面上所有标准协议,云服务或者本地部署都搞得定,微软的SAML、谷歌的OIDC,包括CAS、Oauth、JWT等待各种协议都支持。

2、其次,OAuth2是用来允许用户授权第三方应用访问他在另一个服务器上的资源的一种协议,它不是用来做单点登录的,但我们可以利用它来实现单点登录。

3、单点登录和统一认证中主要的三个协议是OpenID,OAuth,金和SAML,被称为单点登录的三驾马车。这些协议已经有了各种语言版本的实现,本人也在其他文字做了详尽的介绍,这里专门对比下三种协议的异同。

第三方授权就是,委托第三方来对既定的用户进行鉴定,鉴定成功之后,下发信任凭证,信任凭证和用户挂钩,同时可以使用此凭证来去第三方平台,获得该用户开放的部分信息

直白的说,就是将用户授权的工作交给第三方来做,而自己只维护信任凭证,并且获取用户信息。就像我们的QQ和微博一样,你在逛各大论坛的时候,总会有一种途径就是第三方的App登陆。显然这种验证是要在第三方做的,而论坛只需要维护一个token,并且可以获取你的个人信息,然而没什么软用。你如果想用部分功能,还是得注册,因为你相当于论坛只是一个有部分信息的游客,而没有成为它的用户,这种手段可以看成是提高自己访问量或转化率的一种手段吧。其实这种授权方案不一样只用在互联网,部分企业级的网站做资源的共享访问也是这么做的。比如两个网站合作,A站点账户可以登陆B站点,B站点账户可以登陆A站点,这样A站点就能拿到B站点相关资源,反过来也是。就做到了资源共享。

那么这种授权是怎么做的呢?到底安全不安全?那么可能就要引出OAuth协议了。

首先OAuth只是一个授权协议,不是一个实现或是一个中间件。

OAuth1于2007年10月建立,之后又在2009年6月重新修订和发布 http://oauthnet/core/10a/

OAuth10授权流程是什么?

流程很复杂,因为OAuth需要保证授权码和Token在传输的时候不被截取和篡改,所以使用了很多签名反复的验证。

OAuth10的问题:

反复的签名,开放平台本来就面对开发者,但是反复的签名导致开发的流程太过于复杂。

没有引入回跳地址的判断,导致会跳可能会篡改,这样授权码和Token会被Hack掉(10a的时候修复了这个漏洞)。

授权流程过于单一化。

OAuth20的引入:

抽象验证流程

由于OAuth1过于复杂,之后对OAuth进行了改造引入了Oauth20。OAuth的授权过程如下:

(A) 客户端从资源拥有者那里请求授权。授权请求能够直接发送给资源拥有者,或者间接地通过授权服务器这样的中介,而后者更为可取。

(B) 客户端收到一个访问许可,它代表由资源服务器提供的授权。

(C) 客户端使用它自己的私有证书到授权服务器上验证,并出示访问许可,来请求一个访问令牌

(D) 授权服务器验证客户端私有证书和访问许可的有效性,如果验证通过则分发一个访问令牌。

(E) 客户端通过出示访问令牌向资源服务器请求受保护资源。

(F) 资源服务器验证访问令牌的有效性,如果验证通过则响应这个资源请求。

上面只是一个抽象的验证流程,根据上面的抽象流程演化出四种验证模式:

授权码模式

授权码模式和上述的 抽象验证模式流程比较相似:

(A) web客户端通过将终端用户的user-agent重定向到授权服务器来发起这个流程。客户端传入它的客户端标识符、请求作用域、本地状态和一个重定向URI,在访问被许可(或被拒绝)后授权服务器会重新将终端用户引导回这个URI。

(B) 授权服务器验证终端用户(借助于user-agent),并确定终端用户是否许可客户端的访问请求。

(C) 假定终端用户许可了这次访问,授权服务器会将user-agent重定向到之前提供的重定向URI上去。授权服务器为客户端传回一个授权码做获取访问令牌之用。

(D) 客户端通过验证并传入上一步取得的授权码从授权服务器请求一个访问令牌。(需要带上ClientId和Secret,ClientId和Secret是通过平台授予)

(E) 授权服务器验证客户端私有证书和授权码的有效性并返回访问令牌。

授权码模式(implicit grant type)

User-Agent子态适用于客户端不能保存客户端私有证书的App(纯客户端App,无Server参与)。因为可纯客户端的程序不能保存密钥

(A) 客户端将user-agent引导到终端用户授权endpoint。客户端传入它的客户端标识符、请求作用域、本地状态和一个重定向URI,在访问被许可(或被拒绝)后授权服务器会重新将终端用户引导回这个URI。

(B) 授权服务器验证终端用户(通过user-agent)并确认终端用户是许可还是拒绝了客户端的访问请求。

(C) 如果终端用户许可了这次访问,那么授权服务器会将user-agent引导到之前提供的重定向URI。重定向URI会在URI片断{译者注:URI片断是指URI中#号之后的内容}中包含访问令牌。

(D) user-agent响应重定向指令,向web服务器发送不包含URI片断的请求。user-agent在本地保存URI片断。

(E) web服务器返回一个web页面(通常是嵌入了脚本的HTML网页),这个页面能够访问完整的重定向URI,它包含了由user-agent保存的URI片断,同时这个页面能够将包含在URI片断中的访问令牌(和其它参数)提取出来。

(F) user-agent在本地执行由web服务器提供的脚本,该脚本提取出访问令牌并将它传递给客户端。

密码模式

密码模式就是将密码托管给第三方App,但是必须要保证第三方App高度可信。

(A)用户向客户端提供用户名和密码。

(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。

(C)认证服务器确认无误后,向客户端提供访问令牌。

客户端模式

这种模式不需要终端用户的参与,只是Client和Server端的交互。通常只用于Client状态的获取。

(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。

(B)认证服务器确认无误后,向客户端提供访问令牌。

授权流程

这里以授权码方式流程说明,主要流程分为两步,获取授权码和通过授权码获取资源票据:

(A)用户访问客户端,后者将前者导向认证服务器。

(B)用户选择是否给予客户端授权。

(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。

(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。

(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

A步骤中,客户端申请认证的URI,包含以下参数:

response_type:表示授权类型,必选项,此处的值固定为"code"

client_id:表示客户端的ID,必选项

redirect_uri:表示重定向URI,可选项

scope:表示申请的权限范围,可选项

state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

C步骤中,服务器回应客户端的URI,包含以下参数:

code:表示授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。

state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。

D步骤中,客户端向认证服务器申请令牌的HTTP请求,包含以下参数:

grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"。

code:表示上一步获得的授权码,必选项。

redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。

client_id:表示客户端ID,必选项。

E步骤中,认证服务器发送的HTTP回复,包含以下参数:

access_token:表示访问令牌,必选项。

token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。

expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。

refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。

scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。

资源访问过程:

http://localhost:8082/oauth/server/resource/unamedoaccess_token=233730a3d4cdc1af64f78fa80bc13c6e

此处主要由资源服务方实现,对于access_token进行校验。

token过期刷新过程:

客户端使用“refresh_token”访问许可类型和下列参数传入刷新令牌:

refresh_token:

必需参数。与待刷新的访问令牌相关联的刷新令牌。

grant_type=refresh_token&client_id=s6BhdRkqt3&client_secret=8eSEIpnqmM&refresh_token=n4E9O119d

授权服务器必须验证客户端私有证书(如果存在),验证刷新令牌是否有效,以及验证资源拥有者的授权是否仍然有效。如果请求有效,授权服务器则发布一个访问令牌响应,原来的Token失效。以后访问必须使用新Token。

OAuth2看上去很美好,但是细心观察其实还是有一些漏洞的。

参考资料:

http://blogcsdnnet/seccloud/article/details/8192707

http://wwwjustwinitcn/post/8138/

https://blogyorkxinorg/2013/09/30/oauth2-1-introduction

人人网OAuth历程: http://wwwinfoqcom/cn/presentations/dx-renren-authentication-authorization/

OAuth 是一个开放标准的授权框架,它为第三方应用获取资源所有者在资源所在系统或应用上的部分资源提供了一种解决方案。

也就是说,假如你在腾讯云存了一些,现在你想在美图秀秀上编辑这些;此时的 "你" 就是资源所有者,第三方应用就是美图秀秀,而资源服务器就是腾讯云;

这种情况下美图秀秀直接访问腾讯云是获取不到你的的,所以美图秀秀为了能获取到这些照片就需要授权服务器授权(当然,资源服务器和授权服务器有可能是同一个,也有可能是两个不同的服务)

OAuth 就是为这种类似的场景定义的一套标准,目前已经发展到了 OAuth20 。 OAuth20 在 RFC 的文档地址: https://datatrackerietforg/doc/html/rfc6749

下面可以通过一个场景来解释一下, OAuth20 的原理:一个快递员的问题

假设你住在一个大型的小区中,你经常点外卖,而小区有门禁系统,进入的时候需要输密码

为了能让快递员进入,你就需要为他提供一组密码

如果你直接把你的密码给了快递员,那么他就有了和你一样的权限,如果你想取消他的权限,那只能改密码了,这样你还要通知使用该密码的其他人

所以你打算设计一套授权机制,既能让快递员进来,又能限制他的操作并且能随时回收这个密码

于是,你想出了一套办法,完善门禁系统:

此处为什么要给他生成一个令牌,而不是直接给他开门呢?

因为从小区大门到目的地可能会有多个门禁,所以就不用一直等着给快递员开门了;同样的,如果第二天快递员再来时就不需要再获取权限了

密码和令牌都让获取第三方获取用户数据,但是相较于密码,令牌有如下的有点:

令牌能够有效的控制第三方应用的访问权限和访问时长;当然,令牌也是必须要保密的,因为泄露令牌和泄露密码一样,也会造成安全问题,因此一般令牌的有效时间都会设置的比较短

OAuth20 提供了四种授权方式来应对不同的应用场景,

授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。

这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。

第一步,A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权用户数据给 A 网站使用。下面就是 A 网站跳转 B 网站的一个示意链接。

上面 URL 中, response_type 参数表示要求返回授权码( code ), client_id 参数让 B 知道是谁在请求, redirect_uri 参数是 B 接受或拒绝请求后的跳转网址, scope 参数表示要求的授权范围(这里是只读)。

第二步,用户跳转后,B 网站会要求用户登录(如果是未登录的情况下),然后询问是否同意给予 A 网站授权;如果用户同意授权,这时 B 网站就会跳回 redirect_uri 参数指定的网址。跳转时,会传回一个授权码,就像下面这样。

上面 URL 中, code 参数就是授权码。注:这个授权码与客户端一一对应,通常只有10分钟的有效期,并且只能使用一次

第三步,A 网站拿到授权码以后,就可以在后端,向 B 网站请求令牌。

上面 URL 中, client_id 参数和 client_secret 参数用来让 B 确认 A 的身份( client_secret 参数是保密的,因此只能在后端发请求), grant_type 参数的值是 AUTHORIZATION_CODE ,表示采用的授权方式是授权码, code 参数是上一步拿到的授权码, redirect_uri 参数是令牌颁发后的回调网址。

第四步,B 网站收到请求以后,就会颁发令牌。具体做法是向 redirect_uri 指定的网址,发送一段 JSON 数据。

上面 JSON 数据中, access_token 字段就是令牌,A 网站在后端拿到了。

有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。 RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。

第一步,A 网站提供一个链接,要求用户跳转到 B 网站,授权用户数据给 A 网站使用。

上面 URL 中, response_type 参数为 token ,表示要求直接返回令牌。

第二步,用户跳转到 B 网站,登录后同意给予 A 网站授权。这时,B 网站就会跳回 redirect_uri 参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。

上面 URL 中, token 参数就是令牌,A 网站因此直接在前端拿到令牌。

注意,令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring),这是因为 OAuth 20 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。

如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。

第一步,A 网站要求用户提供 B 网站的用户名和密码。拿到以后,A 就直接向 B 请求令牌。

上面 URL 中, grant_type 参数是授权方式,这里的 password 表示"密码式", username 和 password 是 B 的用户名和密码。

第二步,B 网站验证身份通过后,直接给出令牌。注意,这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应,A 因此拿到令牌。

这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。

最后一种方式是凭证式(client credentials),适用于没有前端的命令行应用,即在命令行下请求令牌。

第一步,A 应用在命令行向 B 发出请求。

上面 URL 中, grant_type 参数等于 client_credentials 表示采用凭证式, client_id 和 client_secret 用来让 B 确认 A 的身份。

第二步,B 网站验证通过以后,直接返回令牌。

这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

A 网站拿到令牌以后,就可以向 B 网站的 API 请求数据了。

此时,每个发到 API 的请求,都必须带有令牌。具体做法是在请求的头信息,加上一个 Authorization 字段,令牌就放在这个字段里面。

上面命令中, ACCESS_TOKEN 就是拿到的令牌。

令牌的有效期到了,如果让用户重新走一遍上面的流程,再申请一个新的令牌,很可能体验不好,而且也没有必要。OAuth 20 允许用户自动更新令牌。

具体方法是,B 网站颁发令牌的时候,一次性颁发两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。

上面 URL 中, grant_type 参数为 refresh_token 表示要求更新令牌, client_id 参数和 client_secret 参数用于确认身份, refresh_token 参数就是用于更新令牌的令牌

OAuth20 描述了授权 (Authorization) 的各种方式,但是这些方式中却没有定义如何进行认证 (Authentication)

认证 (Authentication) 和授权 (Autherization 这两个表示的是不同的动作:

OpeID Connect (OIDC)对 OAuth20 进行了扩展,添加了用户认证的功能,并且它和 OAuth20 的流程是相同的。有区别的地方就是它的认证请求的字段中包含 scope=openid 如下所示:

在返回的响应中包含 ID Token ,用于获取用户身份,如下所示:

这里面有几个问题:

首先,

首先需要保证你的 OAuth20 请求是在 HTTPS 协议下发送的,这样可以防止暴露用户的信息。

其次就是一些钓鱼网站;比如,有一个 A 网站需要获取你在 B 网站上的资源或者数据,所以当你进入 A 网站的某个功能时,它会让你跳转到 B 网站,但是很有可能 B 网站是由 A 网站伪造跳转过来的,此时需要你的授权,当你输入账密的时候,你的账密就泄露了;这些钓鱼网站就是用来收集用户的账密信息的,所以当跳到第二个网站的时候一定要证实该网站是不是你注册过的合法的网站

参考连接:

https://datatrackerietforg/doc/html/rfc6749

https://auth0com/intro-to-iam/what-is-oauth-2/

https://wwwcsoonlinecom/article/3216404/what-is-oauth-how-the-open-authorization-framework-workshtml

https://wwwruanyifengcom/blog/2019/04/oauth_designhtml

https://developeroktacom/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc

https://blogrunscopecom/posts/understanding-oauth-2-and-openid-connect

OAuth20是一个授权框架,他规定了客户从授权服务器获取令牌Token的规则。

要理解OAuth20,先要知道为什么会有这个东西产生,或者说他能帮我们解决什么问题,其实简单说他就是帮我们解决了访问安全问题。先看如下的一张图:

显示了我们没有引入任何安全机制情况下的资源访问过程,可以看到正常的用户和恶意的用户都可以通过向资源服务器的接口发送请求获得用户数据。显然恶意用户不该获取数据,他是非法获得,这个情况不应该被允许,需要一种机制保护用户数据。

OAuth20包含了资源拥有者,授权服务器,客户应用,授权服务器,资源服务器。

客户应用: 通常是一个 WebWeb 或者无线应用,它需要访问用户的。

资源服务器: 是一个 webweb 站点 或者 web service web service web service web service API ,用户的受保护。

授权服务器: 在客户应用成功认证并获得授权之后,向客户应用颁发访问令牌Access Token。

资源拥有者: 资源的拥有人,想要分享某些资源给第三方应用。

1)授权码(Authorization Code Token),仅用于授权码授权类型,用于交换获取访问令牌和刷新令牌

2)刷新令牌(Refresh Token),用于去授权服务器获取一个新的访问令牌

3)访问令牌(Access Token),这是OAuth令牌类型中最核心的一个,用于代表一个用户或服务直接去访问受保护的资源

4)Bearer Token,不管谁拿到Token都可以访问资源,像现钞

5)Proof of Possession(PoP) Token,可以校验client是否对Token有明确的拥有权

上面提到了需要提供一种机制来保护数据,OAuth20提供的就是一种授权机制,就是说用户要访问资源必须先通过授权服务器授权拿到Access Token(访问授权),他拿着这个Access Token才能去资源服务器去要他想要的数据,示意图如下:

这里看到我们引入了一个授权服务器,这个授权服务器就是专门负责颁发Access Token的,客户应用需要从授权服务器中获得Access Token,获得后再向资源服务器去获取数据,请求中包含了Token一起发到资源服务器,资源服务器首先要验证这个Token是否合法,如果合法再返回数据给客户应用。

上图中红色圈圈圈起来的就是OAuth20框架协议工作的地方,他规定了客户应用如何获取Access Token,以及如何使用Token的整个过程。

其中核心的授权服务器包括了授权端点,令牌端点,校验端点,注销端点,如下图所示:

OAuth20中规定了多种授权模式,各种模式实现的复杂程度和安全系数不一样,我们先分别看一下四种授权模式:

1)授权码(Authrization Code)模式:

基本流程是先通过前端渠道客户获取授权码,然后通过后端渠道,客户使用Authrization Code去交换Access Token和可选的Refresh Token,这种模式是最安全的模式,因为令牌不会通过user-agent去传递,完整的过程如下图:

授权码模式的优点是比较安全,他可以有token过期时间,而且上面的第四和第五步都是在服务器之间的访问,很难被截获,用户信息也存在服务端,这样就保证了他的安全性。他的缺点是需要进行多次请求才能访问到资源。

授权码模式假定资源拥有者和客户不在一台设备上,他拥有高安全性的保障,目前市面上主流的第三方认证都是采用这种模式。

2)隐式/简化(Implicit)模式

基本流程是Access Token直接通过前端渠道从授权服务器返回,完整的过程如下图:

3)密码(Resource Owner Password)模式

基本流程是使用用户名/密码作为授权方式从授权服务器上获取Access Token,而且一般不支持refresh token,完整的过程如下图:

4)客户端(Client)模式

基本流程是通过后端渠道去获取一个Access Token,因为客户凭证可以使用对称或者非对称加密,该方式支持共享密码和证书,完整的过程如下图:

客户端模式适合用作服务器间通信场景。

授权码模式有一个基本的选择流程,如下图:

在介绍Spring Cloud Security之前,我们先要介绍一下Spring Security。

Spring Security是一套提供了完整的声明式安全访问控制的解决方案。

Spring Security是基于Spring AOP和Servlet过滤器的,它只能服务基于Spring的应用程序。

除常规认证和授权外,它还提供 ACL,LDAP,JAAS,CAS 等高级安全特性以满足复杂环境中的安全需求。

(注:在Spring Security中,Authority和Permission是两个完全独立的概念,两者没有必然的联系。它们之前需要通过配置进行关联。)

安全方案的实现通常分为 认证(Authentication) 授权(Authorization) 两部分。

使用者可以使一个 用户 设备 ,和可以在应用程序中执行某种操作的 其它系统

认证一般通过用户名和密码的正确性校验来完成通过或拒绝。

Spring Security支持的主流认证如下:

Spring Security进行认证的步骤:

++++++++++++++++++++++++++++++++++++++++++++++++++++++

++ 1 用户使用用户名和密码登陆

++

++ 2 过滤器(UsernamePasswordAuthenticationFilter)获取到用户名

++    和密码,将它们封装成Authentication

++

++ 3 AuthenticationManager认证Token(由Authentication实现类传递)

++

++ 4 AuthenticationManager认证成功,返回一个封装了用户权限信息

++    的Authentication对象,包含用户的上下文信息(角色列表)

++

++ 5 将Authentication对象赋值给当前的SecurityContext,建立这个用户

++ 的安全上下文( SecurityContextHoldergetContextsetAuthentication() )

++

++ 6 当用户进行一些受到访问控制机制保护的操作,访问控制机制会依据

++    当前安全的上下文信息来检查这个操作所需的权限

++++++++++++++++++++++++++++++++++++++++++++++++++++++

Spring Security提供了一系列基本组件,如spring-security-acl, spring-security-cas, spring-security-oauth2等。

具体这里就不详述了,读者可以查看官网的介绍。

 

Spring Cloud Security是用于构建微服务系统架构下的安全的应用程序和服务,它可以轻松实现基于微服务架构的统一的安全认证与授权。

Spring Cloud Security相对于Spring Security整合了Zuul,Feign,而且更加完美地整合了OAuth20。

 

OAuth 20是用于授权的行业标准协议。

原理:

OAuth2是用户资源和第三方应用之间的一个中间层。

它把资源和第三方应用隔开,使得第三方应用无法直接访问资源,第三方应用要访问资源需要通过提供 凭证(Token) 来获得OAuth 20授权。

OAuth2的典型例子:

==============================================

== 微信公众号授权提醒

== 页面弹出一个提示框需要获取我们的个人信息

== 单击确定

== 第三方应用会获取我们在微信公众平台中的个人信息

==============================================

OAuth的关键角色:

在用户授权第三方获取私有资源后,第三方通过获取到的token等信息通过授权服务器认证,然后去资源服务器获取资源。

 

密码模式中,资源拥有者负责向客户端提供用户名和密码;

客户端根据用户名和密码箱认证服务器申请令牌,正确后认证服务器发放令牌。

客户端请求参数:

缺点:

用户对客户端高度可信,必须把自己的密码发给客户端,存在被黑客窃取的隐患(不推荐)。

在授权码模式中,客户端是通过其后台服务器与认证服务器进行交互的。

授权码模式的运行流程:

从以上图中我们可以看到客户端服务器和认证服务器需经过2次握手,客户端服务器才能拿到最终的访问和更新令牌。

客户端申请认证的参数:

 

服务器返回的参数:

 

客户端收到授权码以后,附上重定向URI,向认证服务器申请访问令牌。

客户端申请令牌的参数:

 

服务器返回的参数:

 

如果访问令牌已经过期,可以使用更新令牌申请一个新的访问令牌。

通过更新令牌申请访问令牌的参数:

这两种模式不常用,因此在这里就不多叙述了。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » Spring Cloud Gateway + Jwt + Oauth2 实现网关的鉴权操作

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情