单点登录SSO和Oauth2.0 文章2

  OAuth协议,是一种授权协议,不涉及具体的代码,只是表示一种约定的流程和规范。OAuth协议一般用于用户决定是否把自己在某个服务商上面的资源(比如:用户基本资料、照片、视频等)授权给第三方应用访问。

OAuth2.0协议是OAuth协议的升级版,现在已经逐渐成为单点登录(SSO)和用户授权的标准;其官方网址为:https://oauth.net/2/

OAuth 2.0的角色

  获得资源拥有者授权的第三方应用请求受保护的资源采用的不是授权者的凭证,而是一个被称为Access Token的安全令牌。Access Token颁发过程会涉及到若干不同的“实体”,它们在这个过程中扮演者不同的角色,我们通过一个具体的场景来认识一下该过程中涉及到的几种角色。

  • 资源拥有者(RO:Resource Owner):资源的拥有者也是授权者,如果它是一个“人”,一般就是指最终用户
  • 客户端应用(Client):需要取得资源拥有者授权并最终访问受保护资源的应用,如:web网站,移动应用等。
  • 资源服务器(Resource Server):最终承载资源的服务器,它一般体现为一个可被调用的Web API;托管受保护资源的服务器。
  • 授权服务器(Authorization Server):它对用户(一般情况下为资源拥有者)和客户端应用实施认证,并在用户授权的情况下向客户端应用颁发Access Token,能够向客户端颁发令牌。

协议流程

 

OAuth2解决什么问题的?

举个栗子先。小明QQ空间积攒了多年的照片,想挑选一些照片来打印出来。然后小明在找到一家提供在线打印并且包邮的网站(我们叫它PP吧(Print Photo缩写 😂))。

那么现在问题来了,小明有两个方案来得到打印的服务。

  1. 在自己的QQ空间把想要打印的照片下载下来,然后提供给PP(直接发邮件给PP或者网盘共享给PP等等)。
  2. 把自己的QQ账号密码给PP,然后告诉PP我要打印哪些照片。

针对方案(1):小明要去下载这些照片,然后给PP,小明累觉不爱,,,

针对方案(2):小明交出去自己的QQ账号密码,还要告诉PP哪些需要打印,哪些不需要,小明觉得自己有些小秘密不想给PP看,,,

小明觉得很痛苦,,,那么有没有不给PP账号密码,不下载照片,自己选哪些要打印直接扔给PP去打印的办法呢?OAuth走了过来扔给小明一块肥皂...

总结来说,OAuth2 是一个开放授权标准,它允许用户(小明)让第三方应用(PP)访问该用户在某服务的特定私有资源(QQ空间中小明的照片,可以不包含小明的小视频哦)但是不提供账号密码信息给第三方应用(PP)

  1. Resource Owner:资源拥有者,上面栗子中的小明
  2. Resource Server:资源服务器,上面栗子中的QQ空间,它是小明想要分享照片给PP的照片的提供方;
  3. Client:第三方应用客户端,上面栗子中的PP,代指任何可以消费资源服务器的第三方应用;
  4. Authorization Server :授权服务器,管理Resource Owner,Client和Resource Server的三角关系的中间层

其中Authorization server和Resource server可以是独立的服务提供商,也可以是在一起的,比如腾讯提供QQ空间作为资源服务器的同时也提供授权服务。

OAuth2解决问题的关键在于使用Authorization server提供一个访问凭据给Client,使得Client可以在不知道Resource owner在Resource server上的用户名和密码的情况下消费Resource owner的受保护资源

部署OAuth2需要的完成的工作

由于OAuth2引入了Authorization server来管理Resource Owner,Client和Resource Server的三角关系,那么想要用上OAuth2,是实现以下功能的。

  1. 增加一个Authorization server,提供授权的实现,一般由Resource server 来提供。
  2. Resource server 为第三方应用程序提供注册接口。
  3. Resource server 开放相应的受保护资源的API。
  4. Client 注册成为Resource server的第三方应用。
  5. Client 消费这些API。

作为资源服务提供商来说,1,2,3这三件事情是需要完成的。

作为第三方应用程序,要完成的工作是在4和5这两个步骤中。

其中作为Resource owner来说,是不用做什么的,是OAuth2受益的千千万万的最终人类用户。

 

3.1 作为Resource server

在一般情况下,Resource server提供Authorization server服务,主要提供两类接口:

  1. 授权接口:接受Client的授权请求,引导用户到Resource server完成登陆授权的过程。
  2. 获取访问令牌接口:使用授权接口提供的许可凭据来颁发Resource owner的访问令牌给Client,或者由Client更新过期的访问令牌。

除此之外,还需要提供一个第三方应用程序注册管理的服务。通常情况下会为注册完成的第三方应用程序分配两个成对出现的重要参数:

  1. client_id:第三方应用程序的一个标识id,这个信息通常是公开的信息,用来区分哪一个第三方应用程序。
  2. client_secret:第三方应用程序的私钥信息,这个信息是私密的信息,不允许在OAuth2流程中传递的,用于安全方面的检测和加密。

 

作为Client

在Client取得client_id和client_secret之后。使用这些信息来发起授权请求、获取access_token请求和消费受保护的资源。

 

  • (A) Client 请求 Resource Owner 的授权。授权请求可以直接向 Resource Owner 请求,也可以通过 Authorization Server 间接的进行。
  • (B) Client 获得授权许可。
  • © Client 向 Authorization Server 请求访问令牌。
  • (D) Authorization Server 验证授权许可,如果有效则颁发访问令牌。
  • (E) Client 通过访问令牌从 Resource Server 请求受保护资源。
  • (F) Resource Server 验证访问令牌,有效则响应请求。

[A] 用户打开客户端以后,客户端要求用户给予授权。 

[B] 用户同意给予客户端授权。 

[C] 客户端使用上一步获得的授权,向认证服务器申请令牌。 

[D] 认证服务器对客户端进行认证以后,确认无误,同意

[E] 客户端使用令牌,向资源服务器申请获取资源。 

[F] 资源服务器确认令牌无误,同意向客户端开放资源。

在上述的OAuth完整流程中,(A)->(B)->(C)->(D)是授权的过程(参与者有小明PPQQ空间Authorization server);(E)->(F)是消费资源的过程(参与者有PPQQ空间)。

  • (A)小明访问PPPPQQ空间发起授权请求;
  • (B)QQ空间接受PP的授权请求,并返回授权许可PP
  • (C)PP使用授权许可Authorization server发起请求
  • (D)Authorization server验证PP的身份和授权许可,发送访问令牌PP
  • (E)PP访问令牌请求小明存储在QQ空间的照片;
  • (F)QQ空间根据访问令牌,返回小明的照片信息给PP

这其中比较重要的一个概念是访问令牌 ,它代表的信息是整个OAuth2的核心,也是ABCD这些步骤最终要得到的信息。

访问令牌是对PP可以在QQ空间访问小明的哪些信息这个完整权限的一个抽象,比如PP要访问小李在QQ空间的照片,那么就是另外一个访问令牌了。

访问令牌背后抽象的信息有哪些呢?如下3类信息。

  1. 客户端标识(比如PP);
  2. 用户标识(比如小明);
  3. 客户端能访问资源所有者的哪些资源以及其相应的权限。

有了这三类信息,那么资源服务器(Resouce Server)就可以区分出来是哪个第三方应用(Client)要访问哪个用户(Resource Owner)的哪些资源(以及有没有权限)

 

+--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

 

授权

一个客户端想要获得授权,就需要先到服务商那注册你的应用。一般需要你提供下面这些信息:

  • 应用名称
  • 应用网站
  • 重定向 URI 或回调 URL(redirect_uri)

重定向 URI 是服务商在用户授权(或拒绝)应用程序之后重定向用户的地址,因此也是用于处理授权代码或访问令牌的应用程序的一部分。在你注册成功之后,你会从服务商那获取到你的应用相关的信息:

  • 客户端标识 client_id
  • 客户端密钥 client_secret

client_id 用来表识客户端(公开),client_secret 用来验证客户端身份(保密)。

 https://www.coding10.com/section/oauth-2-authorization-code

授权类型

客户端必须得到授权(authorization grant),才能获得令牌(access token),OAuth 2 提出了四种授权模式供我们在不同场景下使用:

OAuth 2.0 列举了四种授权类型,分别用于不同的场景:

  • Authorization Code(授权码 code):服务器与客户端配合使用。
  • Implicit(隐式 token):用于移动应用程序或 Web 应用程序(在用户设备上运行的应用程序)。
  • Resource Owner Password Credentials(资源所有者密码凭证 password):资源所有者和客户端之间具有高度信任时(例如,客户端是设备的操作系统的一部分,或者是一个高度特权应用程序),以及当其他授权许可类型(例如授权码)不可用时被使用。
  • Client Credentials(客户端证书 client_credentials):当客户端代表自己表演(客户端也是资源所有者)或者基于与授权服务器事先商定的授权请求对受保护资源的访问权限时,客户端凭据被用作为授权许可。

下面来具体说说这四种授权。注意重定向一定要用 302。

授权码模式

该方式需要资源服务器的参与,应用场景大概是:

  1. 资源拥有者(用户)需要登录客户端(APP),他选择了第三方登录。
  2. 客户端(APP)重定向到第三方授权服务器。此时客户端携带了客户端标识(client_id),那么第三方就知道这是哪个客户端,资源拥有者确定(拒绝)授权后需要重定向到哪里。
  3. 用户确认授权,客户端(APP)被重定向到注册时给定的 URI,并携带了第三方给定的 code。
  4. 在重定向的过程中,客户端拿到 code 与 client_idclient_secret 去授权服务器请求令牌,如果成功,直接请求资源服务器获取资源,整个过程,用户代理是不会拿到令牌 token 的。
  5. 客户端(APP)拿到令牌 token 后就可以向第三方的资源服务器请求资源了。

User Agent - 用户代理,在这里它代指浏览器;用户代理和图中的 Client 其实是一个系统下的不同组成部分,这个系统在授权场景下就是“客户端”,只不过在这里又把客户端进行了职责功能的分拆,分拆为前端 [User Agent] 和后段[Client] 指的是被授权的第三方应用的后台服务器

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

[B] 用户选择是否给予客户端授权。

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

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

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

 +----------+
     | Resource |
     |   Owner  |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier      +---------------+
     |         -+----(A)-- & Redirection URI ---->|               |
     |  User-   |                                 | Authorization |
     |  Agent  -+----(B)-- User authenticates --->|     Server    |
     |          |                                 |               |
     |         -+----(C)-- Authorization Code ---<|               |
     +-|----|---+                                 +---------------+
       |    |                                         ^      v
      (A)  (C)                                        |      |
       |    |                                         |      |
       ^    v                                         |      |
     +---------+                                      |      |
     |         |>---(D)-- Authorization Code ---------'      |
     |  Client |          & Redirection URI                  |
     |         |                                             |
     |         |<---(E)----- Access Token -------------------'
     +---------+       (w/ Optional Refresh Token)

   Note: The lines illustrating steps (A), (B), and (C) are broken into
   two parts as they pass through the user-agent.

                     Figure 3: Authorization Code Flow

 

上图ABCDE这5个步骤,既是完整的获取访问令牌的一个过程,其中引入了一些其他的概念,比如客户端标识,刷新令牌等和重定向URL等概念,后续会在6. OAuth2附属概念和流程介绍。

  • (A)Client使用浏览器(用户代理)访问Authorization server。也就是用浏览器访问一个URL,这个URL是Authorization server提供的,访问的收Client需要提供(客户端标识,请求范围,本地状态和重定向URL)这些参数。
  • (B)Authorization server验证Client在(A)中传递的参数信息,如果无误则提供一个页面供Resource owner登陆,登陆成功后选择Client可以访问Resource server的哪些资源以及读写权限。
  • (C)在(B)无误后返回一个授权码(Authorization Code)给Client
  • (D)Client拿着(C)中获得的授权码(Authorization Code)和(客户端标识、重定向URL等信息)作为参数,请求Authorization server提供的获取访问令牌的URL
  • (E)Authorization server返回访问令牌和可选的刷新令牌以及令牌有效时间等信息给Client

5.1.1 Authorization Request

对应步骤(A),客户端提供以下参数请求Authorization Server:

  1. response_type:必选。值固定为“code”。
  2. client_id:必选。第三方应用的标识ID。
  3. state:推荐。Client提供的一个字符串,服务器会原样返回给Client。
  4. redirect_uri:必选。授权成功后的重定向地址。
  5. scope:可选。表示授权范围。

比如以下示例:

GET /authorize?response_type=code&client_id=1&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Foauth2&scope=user,photo HTTP/1.1
Host: server.example.com

5.1.2 Authorization Response

对应步骤(C),Authorization Server会返回如下信息:

  1. code:授权码。
  2. state:步骤(A)中客户端提供的state参数原样返回。

比如示例如下:

HTTP/1.1 302 Found
Location: https://client.example.com/oauth2?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

Location头部信息指向步骤(A)提供的redirect_uri地址,同时携带code信息和state信息给client,这样浏览器在重定向的时候就会已GET的方式访问Client提供的redirect_uri,同时Client接收到code信息和state信息。下一步就可以请求access_token了。

5.1.3 Access Token Request

对应步骤(D),客户端提供以下参数请求Authorization Server:

  1. grant_type:必选。固定值“authorization_code”。
  2. code : 必选。Authorization Response 中响应的code。
  3. redirect_uri:必选。必须和Authorization Request中提供的redirect_uri相同。
  4. client_id:必选。必须和Authorization Request中提供的client_id相同。

比如以下示例:

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=123&client_id=1&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Foauth2

5.1.4 Access Token Response

对应步骤(E),Authorization Server会返回如下典型的信息:

  1. access_token:访问令牌。
  2. refresh_token:刷新令牌。
  3. expires_in:过期时间。

比如以下示例:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

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

以 coding 和 github 为例。当我想在 coding 上通过 github 账号登录时:

1、GET 请求 点击登录,重定向到 github 的授权端点:

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

https://github.com/login/oauth/authorize?
  response_type=code&
  client_id=a5ce5a6c7e8c39567ca0&
  redirect_uri=https://coding.net/api/oauth/github/callback&
  scope=user:email
字段描述
response_type 必须,固定为 code,表示这是一个授权码请求。
client_id 必须,在 github 注册获得的客户端 ID。
redirect_uri 可选,通过客户端注册的重定向 URI(一般要求且与注册时一致)。
scope 可选,请求资源范围,多个空格隔开。
state 可选(推荐),如果存在,原样返回给客户端。

返回值:

https://coding.net/api/oauth/github/callback?code=fb6a88dc09e843b33f

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

  • code:表示授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。
  • state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。
字段描述
code 必须。授权码
state

如果出现在请求中,必须包含。

 

授权错误

第一种,客户端没有被识别或错误的重定向 URI,授权服务器没有必要重定向资源拥有者到重定向URI,而是通知资源拥有者发生了错误。

第二种,客户端被正确地授权了,但是其他某些事情失败了。这种情况下下面地错误响应会被发送到客户端,包括在重定向 URI 中。

https://coding.net/api/oauth/github/callback?
  error=redirect_uri_mismatch&
  error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&
  error_uri=https%3A%2F%2Fdeveloper.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch
字段描述
error 必须,必须是预先定义的错误码: 错误码
error_description 可选,错误描述
error_uri 可选,指向可解读错误的 URI
state 必须,如果出现在授权请求中

 

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

  • grant_type:表示使用的授权模式,必选项,此处的值固定为 "authorization_code"。
  • code:表示上一步获得的授权码,必选项。
  • redirect_uri:表示重定向 URI,必选项,且必须与A步骤中的该参数值保持一致。
  • client_id:表示客户端 ID,必选项。 

2、POST 请求 获取令牌 token,当获取到授权码 code 后,客户端需要用它获取访问令牌:

https://github.com/login/oauth/access_token?
  client_id=a5ce5a6c7e8c39567ca0&
  client_secret=xxxx&
  grant_type=authorization_code&
  code=fb6a88dc09e843b33f&
  redirect_uri=https://coding.net/api/oauth/github/callback

出于安全考虑 client_id 和 client_secret 可以通过 HTTP Basic 认证:Authorization: Basic YTVjZTVhNmM3ZThjMzk1NjdjYTA6eHh4eA==

字段描述
grant_type 必须,固定为 authorization_code/refresh_token。
code 必须,上一步获取到的授权码。
redirect_uri 必须(如果请求/authorize接口有),完成授权后的回调地址,与注册时一致。
client_id 必须,客户端标识。
client_secret 必须,客户端密钥。

 

返回值:

{
  "access_token":"a14afef0f66fcffce3e0fcd2e34f6ff4",
  "token_type":"bearer",
  "expires_in":3920,
  "refresh_token":"5d633d136b6d56a41829b73a424803ec"
}

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

  • access_token:表示访问令牌,必选项。
  • token_type:表示令牌类型,该值大小写不敏感,必选项,可以是 bearer 类型或 mac 类型。
  • expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
  • refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
  • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
字段描述
access_token 这个就是最终获取到的令牌。
token_type 令牌类型,常见有 bearer/mac/token(可自定义)。
expires_in 失效时间。
refresh_token 刷新令牌,用来刷新 access_token。

3、获取资源服务器资源,拿着 access_token 就可以获取账号的相关信息了:

curl -H "Authorization: token a14afef0f66fcffce3e0fcd2e34f6ff4" https://api.github.com/user

4、POST 请求 刷新令牌

我们的 access_token 是有时效性的,当在获取 github 用户信息时,如果返回 token 过期:

https://github.com/login/oauth/access_token?
  client_id=a5ce5a6c7e8c39567ca0&
  client_secret=xxxx&
  redirect_uri=https://coding.net/api/oauth/github/callback&
  grant_type=refresh_token&
  refresh_token=5d633d136b6d56a41829b73a424803ec
字段描述
redirect_uri 必须
grant_type 必须,固定为 refresh_token
refresh_token 必须,上面获取到的 refresh_token

返回值:

{
  "access_token":"a14afef0f66fcffce3e0fcd2e34f6ee4",
  "token_type":"bearer",
  "expires_in":3920,
  "refresh_token":"4a633d136b6d56a41829b73a424803vd"
}

refresh_token 只有在 access_token 过期时才能使用,并且只能使用一次。当换取到的 access_token 再次过期时,使用新的 refresh_token 来换取 access_token

  +--------+                                           +---------------+
  |        |--(A)------- Authorization Grant --------->|               |
  |        |                                           |               |
  |        |<-(B)----------- Access Token -------------|               |
  |        |               & Refresh Token             |               |
  |        |                                           |               |
  |        |                            +----------+   |               |
  |        |--(C)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(D)- Protected Resource --| Resource |   | Authorization |
  | Client |                            |  Server  |   |     Server    |
  |        |--(E)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(F)- Invalid Token Error -|          |   |               |
  |        |                            +----------+   |               |
  |        |                                           |               |
  |        |--(G)----------- Refresh Token ----------->|               |
  |        |                                           |               |
  |        |<-(H)----------- Access Token -------------|               |
  +--------+           & Optional Refresh Token        +---------------+

               Figure 2: Refreshing an Expired Access Token

[旧版] 隐式模式

该方式一般用于移动客户端或网页客户端。隐式授权类似于授权码授权,但 token 被返回给用户代理再转发到客户端(APP),因此它可能会暴露给用户和用户设备上的其它客户端(APP)。此外,此流程不会对客户端(APP)的身份进行身份验证,并且依赖重定向 URI(已在服务商中注册)来实现此目的。

基本原理:要求用户授权应用程序,然后授权服务器将访问令牌传回给用户代理,用户代理将其传递给客户端。

     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier     +---------------+
     |         -+----(A)-- & Redirection URI --->|               |
     |  User-   |                                | Authorization |
     |  Agent  -|----(B)-- User authenticates -->|     Server    |
     |          |                                |               |
     |          |<---(C)--- Redirection URI ----<|               |
     |          |          with Access Token     +---------------+
     |          |            in Fragment
     |          |                                +---------------+
     |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
     |          |          without Fragment      |     Client    |
     |          |                                |    Resource   |
     |     (F)  |<---(E)------- Script ---------<|               |
     |          |                                +---------------+
     +-|--------+
       |    |
      (A)  (G) Access Token
       |    |
       ^    v
     +---------+
     |         |
     |  Client |
     |         |
     +---------+

   Note: The lines illustrating steps (A) and (B) are broken into two
   parts as they pass through the user-agent.

                       Figure 4: Implicit Grant Flow

1、同样以 coding 和 github 为例:

https://github.com/login/oauth/authorize?
  response_type=token&
  client_id=a5ce5a6c7e8c39567ca0&
  redirect_uri=https://coding.net/api/oauth/github/callback&
  scope=user:email
字段描述
response_type 必须,固定为 token。
client_id 必须。当客户端被注册时,有授权服务器分配的客户端标识。
redirect_uri 可选。由客户端注册的重定向URI。
scope 可选。请求可能的作用域。
state 可选(推荐)。任何需要被传递到客户端请求的URI客户端的状态。

返回值:

https://coding.net/api/oauth/github/callback#
  access_token=a14afef0f66fcffce3e0fcd2e34f6ff4&
  token_type=token&
  expires_in=3600
字段描述
access_token 必须。授权服务器分配的访问令牌。
token_type 必须。令牌类型。
expires_in 推荐,访问令牌过期的秒数。
scope 可选,访问令牌的作用域。
state 必须,如果出现在授权请求期间,和请求中的 state 参数一样。

授权错误和上面一样

2、用户代理提取令牌 token 并提交给 coding

3、coding 拿到 token 就可以获取用户信息了

curl -H "Authorization: token a14afef0f66fcffce3e0fcd2e34f6ff4" https://api.github.com/user

[旧版] 资源所有者密码模式

用户将其服务凭证(用户名和密码)直接提供给客户端,该客户端使用凭据从服务获取访问令牌。如果其它方式不可行,则只应在授权服务器上启用该授权类型。此外,只有在客户端受到用户信任时才能使用它(例如,它由服务商自有,或用户的桌面操作系统)。

     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          v
          |    Resource Owner
         (A) Password Credentials
          |
          v
     +---------+                                  +---------------+
     |         |>--(B)---- Resource Owner ------->|               |
     |         |         Password Credentials     | Authorization |
     | Client  |                                  |     Server    |
     |         |<--(C)---- Access Token ---------<|               |
     |         |    (w/ Optional Refresh Token)   |               |
     +---------+                                  +---------------+

            Figure 5: Resource Owner Password Credentials Flow

POST 请求 密码凭证流程

https://oauth.example.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID
字段描述
grant_type 必须,固定为 password。
username 必须,UTF-8 编码的资源拥有者用户名。
password 必须,UTF-8 编码的资源拥有者密码。
scope 可选,授权范围。

返回值:

{ 
  "access_token"  : "...",
  "token_type"    : "...",
  "expires_in"    : "...",
  "refresh_token" : "...",
}

如果授权服务器验证成功,那么将直接返回令牌 token,改客户端已被授权。

客户端模式

这种模式只需要提供 client_id 和 client_secret 即可获取授权。一般用于后端 API 的相关操作。

     +---------+                                  +---------------+
     |         |                                  |               |
     |         |>--(A)- Client Authentication --->| Authorization |
     | Client  |                                  |     Server    |
     |         |<--(B)---- Access Token ---------<|               |
     |         |                                  |               |
     +---------+                                  +---------------+

                     Figure 6: Client Credentials Flow

POST 请求 客户端凭证流程:

https://oauth.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET
字段描述
grant_type 必须。必须设置到客户端证书中。
scope 可选。授权的作用域。

返回值

{ 
  "access_token"  : "...",
  "token_type"    : "...",
  "expires_in"    : "...",
}

如果授权服务器验证成功,那么将直接返回令牌 token,改客户端已被授权。

转载自:https://deepzz.com/post/what-is-oauth2-protocol.html

 

posted @   codestacklinuxer  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2023-03-14 alg 序列号调整
2023-03-14 synproxy笔记整理
点击右上角即可分享
微信分享提示