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。

Spring Boot Oauth2的更多相关文章

  1. thymeltesys-基于Spring Boot Oauth2的扫码登录框架

    thymeltesys thymelte是一个基于Spring Boot Oauth2的扫码登录框架,使用PostgreSQL存储数据,之后会慢慢支持其他关系型数据库.即使你不使用整个框架,只使用其中 ...

  2. 3行代码快速实现Spring Boot Oauth2服务

    这里的3行代码并不是指真的只需要写3行代码,而是基于我已经写好的一个Spring Boot Oauth2服务.仅仅需要修改3行数据库配置信息,即可得到一个Spring Boot Oauth2服务. 项 ...

  3. Spring Boot Oauth2缓存UserDetails到Ehcache

    在Spring中有一个类CachingUserDetailsService实现了UserDetailsService接口,该类使用静态代理模式为UserDetailsService提供缓存功能.该类源 ...

  4. spring boot oauth2的一些记录

    oauth2及时从一个项目A申请另一个项目B的访问的时候,不用在项目A输入项目B的用户名和密码,个人理解先跳转到项目B,利用项目B的用户名和密码得到一个code之类的,这里有点像openID,不过不是 ...

  5. spring security oauth2

    https://connect.qq.com/manage.html#/ http://wiki.connect.qq.com/%E7%BD%91%E7%AB%99%E5%BA%94%E7%94%A8 ...

  6. spring boot面试问题集锦

    译文作者:david  原文链接:https://www.javainuse.com/spring/SpringBootInterviewQuestions Q: 什么是spring boot? A: ...

  7. Spring Boot MyBatis配置多种数据库

    mybatis-config.xml是支持配置多种数据库的,本文将介绍在Spring Boot中使用配置类来配置. 1. 配置application.yml # mybatis配置 mybatis: ...

  8. spring boot 项目搭建时,各个依赖的作用

    项目搭建页面 https://start.spring.io/ 各个依赖的作用 List of dependencies for Spring Boot 2.1.5.RELEASE Core DevT ...

  9. Spring Boot Security配置教程

    1.简介 在本文中,我们将了解Spring Boot对spring Security的支持. 简而言之,我们将专注于默认Security配置以及如何在需要时禁用或自定义它. 2.默认Security设 ...

随机推荐

  1. 详解Django自定义过滤器

    django过滤器的本质是函数,但函数太多了,为了显示自己的与众不同,设计者们想了个名字过滤器... django有一些内置的过滤器,但和新手赛车不多(把字母转成小写,求数组长度,从数组中取一个随机值 ...

  2. 需要记忆的几个sql语句

    链接查询: 1.查询两个表,在where中定义连接条件: select student.sno,sname,ssex,sage,sdept,cno,grade. from student,sc whe ...

  3. 解析session与cookie

    Session和Cookie相关概念 Session和Cookie都是有服务器生成的. Session和Cookie都是键值对形式保存,主要用于存储特定的一些状态值. Session保存在服务器,Co ...

  4. 计算从哪天起应该购买预售火车票.cs

    代码直接CSC编译即可. 计算从哪天起应该购买预售火车票.cs using System; using System.Diagnostics; using System.IO; class Progr ...

  5. opencv:摄像头和视频的读取

    示例代码: #include <opencv.hpp> using namespace cv; int main() { VideoCapture Capture(); //打开默认摄像头 ...

  6. ORACLE expdp \ impdp \ exp \ imp

    (转自:http://www.cnblogs.com/lanzi/archive/2011/01/06/1927731.html) EXPDP命令行选项1. ATTACH该选项用于在客户会话与已存在导 ...

  7. Android自定义控件之仿美团下拉刷新

    美团的下拉刷新分为三个状态: 第一个状态为下拉刷新状态(pull to refresh),在这个状态下是一个绿色的椭圆随着下拉的距离动态改变其大小. 第二个部分为放开刷新状态(release to r ...

  8. UI-不常用控件 UIActivityIndicatorView、UIProgressView、UISegmentedControl、UIStepper、UISwitch、UITextView、UIAlertController

    1 //UIActivityIndicatorView //小菊花,加载================================================================ ...

  9. 【python】import问题总结

    一.绝对引用 首先总结一下import的各种姿势: 1.import package 读这个包的__init__.py 2.import module 读这个模块全部内容 3.import packa ...

  10. vim自动打开跳到上次的光标位置

    只需要vimrc里面加一个稍微复杂一点的autocmd就搞定了: if has("autocmd") au BufReadPost * && line(" ...