oauth2.0系统学习1-理论

  • 时间:
  • 来源:互联网
  • 文章标签:

一、概念和理论

1.1、快递员问题

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

01) 问题描述

我经常点外卖,每天都有外卖员来送参。我必须找到一个办法,让快递员通过门禁系统,进入小区。
如果我把自己的密码,告诉快递员,他就拥有了与我同样的权限,就可以自由出入小区,这对小区的安全造成影响。
你可以会想,每次收到外卖就改一次密码,这样就可以他进入小区的权力,但是这很麻烦,因为第一,我要自己去修改密码,第二,我还得通知我的家人和亲密的朋友修改后的密码。那么有没有办法,既可以让外卖人员自由进入小区,而又不必密码呢。比如说一个临时凭证

02) 需求描述

  1. 每次外卖人员来送餐,我希望给外卖人员一个凭证,而非密码。
  2. 凭证需要有个过期时间,防止外卖人员一直持有这个凭证。
  3. 凭证只能到A栋楼2层201房间门口,不能去其他楼,同时也不能去A栋楼其他楼层。

03) 设计凭证

  1. 门禁系统的密码输入器下面,增加一个按钮,叫做"获取授权"。快递员去申请授权。

  2. 申请前,我和快递员做了一个约定,每次申请的时候,需要把快递员工号发给我,同时我这里记录下这个工号。

  3. 他按下按钮以后,屋主(也就是我)的手机就会跳出对话框,有人正在要求授权。系统还会显示该快递员的姓名、工号和所属的快递公司。我拿出我记录的工号和系统的工号对比,只有相等,我才认为这个快递员是我授权的。

  4. 我确认请求属实,就点击按钮,告诉门禁系统,我同意给予他进入小区的授权。

  5. 门禁系统得到我的确认以后,向快递员显示一个进入小区的令牌(access token)。只在短期内(比如七天)有效。且只能去我所在的那层楼。

  6. 快递员向门禁系统输入令牌,进入小区。

1.2、oauth2.0是为了解决什么样的问题

我们经常遇到这种情况,假设有个网址W1,可以将用户储存在W2的照片,冲印出来,用户U1使用该功能,必须让W1读取自己储存在W2上的照片,这个时候应该怎么办呢?

传统的做法:

  1. 将W2的账号密码告诉W1,但是这样做有一下几大缺陷
    1. W1可能保存W2的账号密码,不安全
    2. W1拥有了获取用户储存在W2所有资料的权力,用户没法限制W1获得授权的范围和有效期。
    3. 用户只有修改密码,才能收回赋予W1的权力。但是这样做,会使得其他所有获得用户授权的第三方应用程序全部失效。
    4. 只要有一个第三方应用程序被破解,就会导致用户密码泄漏,以及所有被密码保护的数据泄漏。

现在的做法:

  1. 使用oauth2.0 来解决上面的问题。

1.3、 专用名词

01) 授权过程名词

  1. client:第三方应用程序或者客户端,即W1

  2. HTTP service: 服务提供商,即W2

  3. Resource Owner:资源所有者,即U1

  4. User Agent:用户代理,本文中就是指浏览器。

  5. Authorization server:认证服务器

    1. 服务提供商处理认证的服务器。
  6. Resource server:资源服务器

    1. 服务提供商存放资源的服务器
    2. 一般它与认证服务器在同一台服务器中
  7. clinet Identifier:客户端标识符,即W1向W2申请的clinet Id

  8. redicrection ulr:重定向的url

  9. user authenticates:用戶 确定 授权

  10. authorization code:授权码

  11. access token:访问令牌

  12. optional refresh token:可选的刷新令牌

02) 授权认证参数说明

  1. code:授权码
    1. 授权码。
    2. 有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。
    3. code与客户端ID和重定向URI,是一一对应关系。
  2. state:户端的当前状态
    1. 如果客户端的请求中包含这个参数,认证服务器的回应也必须包含这个参数。
  3. response_type:授权类型,具体看服务器定义
  4. client_id:客户端的ID
  5. redirect_uri:表示重定向URI
  6. scope:申请的权限范围
  7. grant_type:使用的授权模式
  8. access_token:访问令牌
  9. token_type:令牌类型,大小写不敏感,可以是bearer类型或mac类型。
  10. expires_in:过期时间,单位为秒。
  11. refresh_token:更新令牌,用来获取下一次的访问令牌。
  12. scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
  13. password:密码
  14. username:用户名
  15. granttype:授权类型,具体看服务器定义
  16. refresh_token:更新令牌

1.4、 授权模式

  1. 授权码模式:authorization code
  2. 简化模式: implicit
  3. 密码模式: resource owner password credentials
  4. 客户端模式: client credentials

01) 授权码模式

  1. 功能最完整、流程最严密的授权模式。

在这里插入图片描述

步骤如下:

  1. (A) 用户访问客户端,客户端将用户导向认证服务器。

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

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

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

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

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

GET /authorize?
	response_type=code&
	client_id=1111&
	state=2222&
	redirect_uri=https://www.baidu.com
  1. response_type=code :授权类型,这里表示授权码模式
  2. client_id:客户端id为1111
  3. 客户端状态:2222
  4. redirect_uri:重定向地址为https://www.baidu.com

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

https://www.baidu.com?code=xxxxx&state=2222
  1. code:授权码
  2. https://www.baidu.com:重定向地址

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

...?grant_type=authorization_code&
	code=xxxxx&
	redirect_uri=https://www.baidu.com&
	clientId=1111
  1. grant_type:表示使用的授权模式

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

{
   "access_token":"2YotnFZFEjr1zCsicMWpAA",
   "token_type":"example",
   "expires_in":3600,
   "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
   "example_parameter":"example_value"
 }
  1. access_token:访问令牌
  2. token_type:令牌类型,大小写不敏感,可以是bearer类型或mac类型。
  3. expires_in:过期时间,单位为秒。
  4. refresh_token:更新令牌,用来获取下一次的访问令牌。
  5. scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。

02) 简化模式

  1. 不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤。
  2. 所有步骤在浏览器中完成,令牌对访问者是可见的
  3. 客户端不需要认证。

在这里插入图片描述

步骤如下:

  1. (A)客户端将用户导向认证服务器。
  2. (B)用户决定是否给于客户端授权。
  3. ©假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。
  4. (D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
  5. (E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
  6. (F)浏览器执行上一步获得的脚本,提取出令牌。
  7. (G)浏览器将令牌发给客户端。

A步骤中,客户端发出的HTTP请求,包含以下参数:

GET /authorize?
	response_type=token&
	client_id=1111&
	state=2222&
    redirect_uri=https://www.baidu.com

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

....#access_token=2YotnFZFEjr1zCsicMWpAA&
 state=2222&
 token_type=example&
 expires_in=3600
  1. 参数前面是#

1.5、 密码模式

  1. 用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。
  2. 通常用在用户对客户端高度信任的情况下,才能考虑使用这种模式。
  3. 使用场景
    1. 微服务集群中单点登陆问题

在这里插入图片描述

  1. (A)用户向客户端提供用户名和密码。
  2. (B)客户端将用户名和密码发给认证服务器,向后者请求令牌。
  3. ©认证服务器确认无误后,向客户端提供访问令牌。

B步骤中,客户端发出的HTTP请求,包含以下参数:

 POST /grant_type=password&
 username=1&
 password=2
  1. grant_type:授权类型,此处的值固定为"password",必选项。
  2. username:用户名,必选项。
  3. password:用户的密码,必选项。
  4. scope:权限范围,可选项。

C步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。

 {
   "access_token":"2YotnFZFEjr1zCsicMWpAA",
   "token_type":"example",
   "expires_in":3600,
   "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
   "example_parameter":"example_value"
 }

1.6、 客户端模式

  1. 以客户端的名义,向"服务提供商"进行认证。
  2. 严格地说,客户端模式并不属于OAuth框架所要解决的问题。
  3. 用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。

在这里插入图片描述

  1. (A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
  2. (B)认证服务器确认无误后,向客户端提供访问令

A步骤中,客户端发出的HTTP请求,包含以下参数:

....?grant_type=client_credentials
  1. granttype:授权类型,此处的值固定为"clientcredentials",必选项。
  2. scope:权限范围,可选项。

B步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。

 {
   "access_token":"2YotnFZFEjr1zCsicMWpAA",
   "token_type":"example",
   "expires_in":3600,
   "example_parameter":"example_value"
 }

1.7、更新令牌

  1. 如果用户访问的时候,客户端的"访问令牌"已经过期,可以使用"更新令牌"申请一个新的访问令牌。

客户端发出更新令牌的HTTP请求,包含以下参数

...?grant_type=refresh_token&
refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
  1. granttype:授权类型,此处的值固定为"clientcredentials",必选项。
  2. scope:权限范围,可选项。
  3. refresh_token:更新令牌,必选项。

本文链接http://www.taodudu.cc/news/show-1781946.html