Spring Boot Oauth2
Oauth2是描述无状态授权的协议(授权框架),因为是无状态,所以我们不需要维护客户端和服务器之间的会话。
Oauth2的工作原理:
此协议允许第三方客户端代表资源所有者访问受保护资源,Oauth2有四个基本角色:
资源所有者-就是资源的所有者 resource owner
资源服务器-托管所有受保护资源的服务器
客户端-访问资源服务器的应用程序
授权服务器-处理客户端发出访问令牌的服务器,这可以是与资源服务器相同的服务器
此外,有两种类型的令牌:
访问令牌(accessToken),通常具有有限的生命周期,并允许客户端听过在请求标头中包含此令牌来访问受保护资源
刷新令牌(refreshToken),刷新具有更长的生命周期的令牌,用于在新的访问令牌到期后获取新访问令牌(无需再次向服务器发送凭据)
一般的访问令牌和刷新令牌周期设置为多久才更合适呢?
阿里巴巴速卖通授权产生的Token,AccessToken有效期时间是10个小时,RefreshToken有效时间是半年;QQ的AccessToken有效期时间是30天,因为AccessToken的有效期时间比较长,所以并没有RefreshToken的说法;微信的AccessToken是2个小时,RefreshToken是30天;新浪的AccessToken的有效期是7天;一般accessToken设置短一点一到两个小时,accessToken时间太长一旦accessToken泄露就会
RefreshToken可以设置长一点。
客户端需要在服务器上注册才能接受客户端ID(clientId)和客户端秘钥(clientSercet),这些客户端id和客户端秘钥稍后在请求访问令牌时使用。每个令牌具有由用户在于授权服务器通信时定义的范围(例如,用户授权客户端应用访问资源服务器上的某些资源)。
Oauth2定义了4种不同的授权类型。这些授权类型定义客户端和身份验证/资源服务器的交互。
授权码模式-机密客户端基于重定向的流程,客户端通过用户代码(web浏览器等)与服务器进行通信,典型的web服务器。
隐式类型(简化模式)-不通过第三方应用程序的服务器,直接在浏览器上向认证服务器申请令牌,跳过了“授权码”这个步骤,所有步骤在浏览器中完成,令牌对访问者可见,且客户端不需要认证。
资源所有者密码凭证(密码模式)-与受信任的客户端一起使用,用户凭证将传给客户端,然后传给认证服务器并交换访问和刷新令牌。
客户端凭证-在客户端本身是资源所有者(一个客户端不与多个用户一起运行)时使用,客户端凭证直接交换给令牌。
运行流程:摘自RFC 6749
(A):用户打开客户端之后,客户端要求用户给予授权
(B):用户同意给予客户端授权
(C):客户端使用(B)步骤获得的授权,像认证服务器申请令牌
(D):认证服务器对客户端进行认证以后,确认无误,同意发放令牌(accessToken)。
(E):客户端使用(D)步骤获得的accessToken,向资源服务器申请获取资源。
(F):资源服务器确定令牌无误之后,同意向客户端开放保护资源。
B步骤中,用户怎么给予客户端授权呢??
只有客户端获得授权,才能向认证服务器去申请访问令牌。从而根据这个令牌去向资源服务器去请求获得资源。
客户端的授权模式有四种,就是上面说的四种模式,这边主要对这四种模式进行详细讲解。
1、授权码模式:通过客户端的后台服务器与认证服务器进行交互。流程如下:
(A):用户访问客户端,客户端将用户导向认证服务器,也就是引导直接去访问认证服务器
(B):然后用户选择是否给予客户端授权
(C):假如用户给予授权,认证服务器则将用户导向客户端实现指定的“重定向URI”(redirection URI),同时附上一个授权码。
(D):当客户端收到这个授权码之后,附上早先的“重定向URI”,直接去访问认服务器向认证服务器去申请accessToken(令牌)。
(E):认证服务器确认了Authorization Code(授权码)和Redirection URI(重定向URI)无误之后,向客户端返回访问令牌(accessToken)和刷新令牌(refreshToken);
A步骤中,客户端申请授权码的URI中需要一些参数:
response_type:标识授权类型,必选项,此处的值固定为“code”
clientId:客户端ID,必选项
redirect_uri:标识重定向URI,此处为可选项
scope:表示申请的权限范围,可选项
state:表示客户端当前的状态,可以指定任意值,认证服务器会原封不动的返回这个值。
C步骤中,认证服务器回应给客户端的URI,必须包括以下的参数。
code:表示授权码,必选项。该码的有效期应该会很短,通常设为10分钟,客户端只能用这个授权码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI是一一对应的关系。
state:如果客户端的请求中包含这个参数,认证服务器返回的应该是这个一模一样的参数。
D步骤中,客户端根据授权码去向认证服务器申请accessToken(令牌)的请求,包含以下几个参数:
grant_type:表示使用的是授权模式,必选项,此处的值固定为“authorization_code”,
code:表示用于再给客户端授权的时候获得的授权码,也就是C步骤中获得的授权码。
redirect_uri:表示重定向uri,必选项,且必须为A步骤中参数的值保持一致。
clientId:表示客户端ID,表示的是必选项。
E步骤中,认证服务器对授权码和重定向URI进行认证之后,返回的Http恢复包括以下的参数:
accessToken:表示授权令牌,必选项。
token_type:表示令牌类型,该值的大小写不敏感,可以为bearer类型或者是mac类型
expires_in:表示过期时间,单位为秒,如果省略这个参数,必须使用其他的方式设置过期时间。
refreshToken:表示更新令牌,作用是为了下一次获取访问令牌,也就是accessToken。可选项,有的也没有设置,但是尽量设置。
scope:表示权限范围,如果与客户端申请授权码的一致,那么这一步可以省略。
其实我们可以采用postMan去获得accessToken如下,这是使用postMan去获得accessToken的参数:
下图则是获得的accessToken:
2、简化模式或者隐式模式(implicit grant type):不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了“获得授权码”这个步骤。所有的步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
(A):跟之前的一样,客户端将用户导向认证服务器
(B):用户决定是否给予客户端授权
(C):假设用户给予授权,认证服务器将用户导向客户端指定的“重定向URI”,并在URI的Hash部分包含了访问令牌(accessToken)
(D):浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值
(E):资源服务器返回一个网页,其中包含的代码可以获得hash值中的令牌。
(F):浏览器执行上一步获得的脚本,提取出令牌
(G):浏览器将accessToken(访问令牌)发给客户端
3、密码模式:用户向客户端提供自己的用户名和密码,客户端使用这些信息向服务提供商索要授权。
(A):用户向客户端提供用户名和密码。
(B):客户端向认证服务器请求访问令牌(accessToken)
(C):认证服务器确认无误之后,向客户端提供accessToken(访问令牌)
4、客户端模式:指客户端以自己的名义,而不是以用户的名义,向服务器提供商进行认证,严格的说客户端模式并不属于oauth框架索要解决的问题,在这种模式中,用户直接向客户端注册,客户端以自己的名义要求服务器提供商提供服务,其实不存在授权问题。
(A):客户端直接向认证服务器去进行身份认证,并要求一个访问令牌
(B):认证服务器进行认证之后,向客户端返回一个accessToken。
posted on 2018-07-17 19:14 zzzhouheng 阅读(4670) 评论(0) 编辑 收藏 举报