OAuth grant types:Authorization code grant type

什么是OAuth授权类型?

OAuth授权类型确定OAuth进程中涉及的步骤的确切顺序。授权类型还影响客户端应用程序在每个阶段与OAuth服务通信的方式,包括访问令牌本身的发送方式。因此,授权类型通常被称为“OAuth流”

在客户端应用程序可以启动相应的流之前,必须将OAuth服务配置为支持特定的授权类型。客户机应用程序指定要在发送给OAuth服务的初始授权请求中使用的授权类型。

有几种不同的授予类型,每种类型都有不同程度的复杂性和安全性考虑。我们将重点讨论“授权代码”和“隐式”授权类型,因为它们是目前最常见的授权类型。

OAuth scopes

对于任何OAuth授权类型,客户机应用程序都必须指定要访问的数据以及要执行的操作类型,它使用它发送给OAuth服务的授权请求的scope参数来实现这一点。

对于基本OAuth,客户端应用程序可以请求访问的范围对于每个OAuth服务都是唯一的。由于作用域的名称只是一个任意文本字符串,因此不同的提供程序之间的格式可能会有很大的差异。有些甚至使用完整URI作为作用域名称,类似于REST API端点。例如,当请求对用户的联系人列表进行读取访问时,根据所使用的OAuth服务,作用域名称可能采用以下任何形式:

scope=contacts
scope=contacts.read
scope=contact-list-r
scope=https://oauth-authorization-server.com/auth/scopes/user/contacts.readonly 

然而,当OAuth用于身份验证时,通常使用标准化的OpenID连接作用域。例如,scope openid概要文件将授予客户机应用程序对预定义的用户基本信息集的读取权限,例如他们的电子邮件地址、用户名等。稍后我们将进一步讨论OpenID Connect。

Authorization code grant type

授权代码授权类型最初看起来相当复杂,但实际上比您熟悉一些基本知识后想象的要简单。

简言之,客户机应用程序和OAuth服务首先使用重定向来交换一系列基于浏览器的HTTP请求,以启动流。询问用户是否同意请求的访问。如果他们接受,客户端应用程序将被授予“授权代码”。然后,客户端应用程序与OAuth服务交换该代码以接收“访问令牌”,它们可以使用该令牌进行API调用以获取相关的用户数据。

从代码/令牌交换开始发生的所有通信都通过一个安全、预配置的后台通道发送到服务器,因此最终用户看不见。当客户端应用程序首次向OAuth服务注册时,就会建立此安全通道。此时,还会生成一个客户机密钥,客户机应用程序在发送这些服务器到服务器请求时必须使用该密钥对自身进行身份验证。

由于最敏感的数据(访问令牌和用户数据)不是通过浏览器发送的,因此这种授权类型可以说是最安全的。如果可能,服务器端应用程序最好总是使用这种授权类型。

在这里插入图片描述

1.授权请求

客户端应用程序向OAuth服务的/authorization端点发送请求,请求访问特定用户数据的权限。请注意,端点映射可能因提供商而异,应该始终能够根据请求中使用的参数识别端点。

GET /authorization?client_id=12345&redirect_uri=https://client-app.com/callback&response_type=code&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1
Host: oauth-authorization-server.com 

此请求包含以下值得注意的参数,通常在查询字符串中提供:

  • client_id
    包含客户端应用程序唯一标识符的必需参数。当客户端应用程序向OAuth服务注册时,会生成此值。
  • redirect_uri
    向客户端应用程序发送授权代码时,用户浏览器应重定向到的URI。这也称为“回调URI”或“回调端点”。许多OAuth攻击都是基于此参数验证中的漏洞。
  • response_type
    确定客户端应用程序预期的响应类型,以及它希望启动的流。对于授权代码授权类型,值应为code。
  • scope
    用于指定客户端应用程序要访问的用户数据子集。注意,这些可能是OAuth提供程序设置的自定义范围,也可能是OpenID Connect规范定义的标准化范围。稍后我们将更详细地介绍OpenID Connect。
  • state
    存储绑定到客户端应用程序上当前会话的唯一、不可用的值。OAuth服务应该在响应中返回这个确切的值以及授权代码。通过确保对其/回调端点的请求来自发起OAuth流的同一个人,此参数作为客户端应用程序的CSRF令牌的一种形式。

2. User login and consent

当授权服务器收到初始请求时,它会将用户重定向到登录页面,在该页面上会提示用户登录到OAuth提供程序的帐户。例如,这通常是他们的社交媒体帐户。

然后,客户机应用程序将向它们显示一个要访问的数据列表。这是基于授权请求中定义的范围。用户可以选择是否同意此访问。

需要注意的是,一旦用户批准了客户机应用程序的给定范围,只要用户仍然拥有与OAuth服务的有效会话,该步骤就会自动完成。换句话说,当用户第一次选择“使用社交媒体登录”时,他们需要手动登录并给予同意,但如果他们稍后重新访问客户端应用程序,通常只需单击一下即可重新登录。

3. Authorization code grant

如果用户同意请求的访问,他们的浏览器将重定向到授权请求的redirect_uri参数中指定的/callback 端点。生成的GET请求将包含授权代码作为查询参数。根据配置,它还可以发送与授权请求中的值相同的状态参数。

GET /callback?code=a1b2c3d4e5f6g7h8&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.com 

4. Access token request

一旦客户机应用程序收到授权码,它需要将其交换为访问令牌。为此,它向OAuth服务的/token端点发送服务器到服务器POST请求。从这一点开始,所有通信都在安全的后台通道中进行,因此攻击者通常无法观察或控制。

POST /token HTTP/1.1
Host: oauth-authorization-server.com
…
client_id=12345&client_secret=SECRET&redirect_uri=https://client-app.com/callback&grant_type=authorization_code&code=a1b2c3d4e5f6g7h8 

除了client_id=12345和code外,您还将注意到以下新参数:

  • client_secret
    客户端应用程序必须通过包括在向OAuth服务注册时分配的密钥来进行自身身份验证。
  • grant_type
    用于确保新端点知道客户端应用程序要使用的授权类型。在这种情况下,应将其设置为授权代码

5. Access token grant

OAuth服务将验证访问令牌请求。如果一切正常,服务器将通过向客户端应用程序授予具有请求范围的访问令牌来响应。

{
  "access_token": "z0y9x8w7v6u5",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid profile",
  …
} 

6. API call

现在客户端应用程序有了访问代码,它最终可以从资源服务器获取用户的数据。为此,它对OAuth服务的/userinfo端点进行API调用。访问令牌在Authorization:Bearer标头中提交,以证明客户端应用程序有权访问此数据。

GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization: Bearer z0y9x8w7v6u5 

7. Resource grant

资源服务器应验证令牌是否有效以及它是否属于当前客户端应用程序。如果是这样,它将根据访问令牌的范围发送请求的资源,即用户的数据。

{
  "username":"carlos",
  "email":"carlos@carlos-montoya.net",
  …
}

客户端应用程序最终可以将此数据用于其预期目的。在OAuth身份验证的情况下,它通常被用作一个ID来授予用户一个经过身份验证的会话,从而有效地将用户登录。

Implicit grant type看链接把,翻译太累了:

https://portswigger.net/web-security/oauth/grant-types

posted @ 2021-08-17 15:33  Zeker62  阅读(125)  评论(0编辑  收藏  举报