跳转到主要内容
Chinese, Simplified

需要使用令牌保护应用程序?您正在寻找OAuth 2.0安全框架。它具有Web,移动和IoT客户端的流程,以及用于管理令牌生命周期的有用API。最初作为授予第三方访问社交个人资料的简单有效的解决方案,已经发展到支持各种领域的应用程序,甚至是最严格的安全要求。

1.使用OAuth 2.0进行基于令牌的安全性


令牌已成为保护互联网上应用程序的流行模式。开发人员喜欢它的概念简单性,架构师能够设计具有良好分离的安全角色的应用程序。然而,看似容易将基于令牌的安全潜伏陷阱陷入困境。

为了建立一个处理令牌的坚实框架,具有明显平衡的安全性和易用性,同时借鉴早期成功点击(特别是最初的OAuth)的经验教训,来自互联网社区的工程师设计了OAuth 2.0并将其作为RFC 6749发布于2012。

OAuth 2.0框架中的关键方面是故意保持开放和可扩展的。基本RFC 6749指定了四种安全角色,并引入了四种方法,称为授权授权,以便客户端获取访问令牌。其余的,例如令牌内的内容,留给实施者或未来的扩展填写。

2. OAuth中的四个角色


OAuth定义了四个角色,清晰地分离了他们的顾虑。这与将安全相关的复杂性转移到专用授权服务器相结合,可以快速推出具有一致安全属性的受OAuth 2.0保护的应用程序和服务。

资源所有者

通常意味着最终用户。 该术语反映了OAuth的初始目的,代表用户提供第三方软件访问,但框架的使用已经超出了这一范围。

资源服务器

受保护资产,通常是Web API,需要令牌才能访问。 令牌验证逻辑可以保持非常小,也可以是无状态的。

客户

应用程序 - 基于Web,移动,桌面或基于设备的应用程序,需要获取令牌才能访问资源服务器。 由于复杂性转移到授权服务器,因此客户端OAuth逻辑很简单。

授权服务器

在成功验证最终用户并确保所请求的访问权限可以通过最终用户的同意,应用策略或其他方式后,向客户端发出访问令牌的专用服务器。

 

3.客户如何获得令牌?


为了获得访问令牌,客户端需要向授权服务器提供有效的授权(凭证)。

如果有一件事经常让OAuth 2.0的新人望而却步,那就是为他们的应用选择合适的补助金。 如果您知道您拥有的客户端类型(网络,移动设备等),那么选择就会变得很明显。

这是一个粗略的指南:

Grant type Client type / Use case
Authorisation code Intended for traditional web applications with a backend as well as native (mobile or desktop) applications to take advantage of single sign-on via the system browser.
Implicit Intended for browser-based (JavaScript) applications without a backend.
Password For trusted native clients where the application and the authorisation server belong to the same provider.
Client credentials For clients, such as web services, acting on their own behalf.
Refresh token A special grant to let clients refresh their access token without having to go through the steps of a code orpassword grant again.
SAML 2.0 bearer Lets a client in possession of a SAML 2.0 assertion (sign-in token) exchange it for an OAuth 2.0 access token.
JWT bearer Lets a client in possession of a JSON Web Token (JWT) assertion from one security domain exchange it for an OAuth 2.0 access token in another domain.
Device code For devices without a browser or with constrained input, such as a smart TV, media console, printer, etc.
Token exchange Lets applications and services obtain an access token in delegation and impersonation scenarios.

3.1授权代码流程示例


现在,我们将通过一个客户端的示例,使用授权代码授权从OAuth 2.0授权服务器获取访问令牌。 此授权主要用于Web应用程序。

客户端需要执行两个步骤来获取令牌,第一个涉及浏览器,第二个步骤是反向通道请求。 这就是为什么这一系列步骤也称为代码流。

  Step 1 Step 2
Purpose 1. Authenticate the user
2. Authorise the client
1. Authenticate client (optional)
2. Exchange code for token(s)
Via Front-channel request
(browser redirection)
Back-channel request
(app to web server)
To Authorisation endpoint Token endpoint
Result on success Authorisation code
(step 2 input)
Access token
Refresh token (optional)

代码流程:第1步


客户端通过授权请求将浏览器重定向到授权服务器来启动代码流。

示例重定向到授权服务器:

HTTP/1.1 302 Found

Location: https://authz.c2id.com/login?

response_type=code &

scope=myapi-read%20myapi-write &

client_id=s6BhdRkqt3 &state=af0ifjsldkj &

redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb

 

授权请求参数在URI查询中编码:

  • response_type:设置为code以指示授权代码流。
  • scope:指定请求的令牌的范围。如果省略,授权服务器可能会采用某个默认范围。
  • client_id:授权服务器上的客户端的标识符。当客户端通过客户端注册API,开发人员控制台或其他方法向授权服务器注册时,将分配此标识符。
  • state:客户端设置的可选opaque值,用于维护请求和回调之间的状态。
  • redirect_uri:授权响应的客户端回调URI。如果省略,授权服务器将采用客户端的默认注册重定向URI。

在授权服务器处,通常通过检查用户是否具有有效会话(由浏览器cookie建立)来验证用户,并且如果没有,则通过提示用户登录来验证用户。之后,服务器将通过询问用户的同意,应用规则或策略,或通过其他方式来确定客户端是否被授权。

然后,授权服务器将使用授权代码(成功时)或错误代码调用客户端redirect_uri(如果访问被拒绝,或者发生了一些其他错误,则检测到这样的格式错误的请求)。

HTTP/1.1 302 Found

Location: https://client.example.org/cb?

code=SplxlOBeZQQYbYS6WxSbIA &

state=af0ifjsldkj


客户端必须验证状态参数,并使用代码继续下一步 - 交换访问令牌的代码。

代码流程:第2步


授权代码是一个中间凭证,它对在步骤1中获得的授权进行编码。因此,它对客户端是不透明的,只对授权服务器有意义。要检索访问令牌,客户端必须将代码提交给授权服务器,但这次使用直接反向通道请求。这样做有两个原因:

在显示令牌之前,使用授权服务器对机密客户端进行身份验证;
将令牌直接传递给客户端,从而避免将其暴露给浏览器。
令牌代码交换发生在授权服务器的令牌端点:

POST /token HTTP/1.1

Host: openid.c2id.com

Content-Type: application/x-www-form-urlencoded

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

grant_type=authorization_code &

code=SplxlOBeZQQYbYS6WxSbIA &

redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb


客户端ID和密钥通过Authorization标头传递。除了HTTP基本身份验证之外,OAuth 2.0还支持使用JWT进行身份验证,JWT不会使用令牌请求公开客户端凭据,因此已过期,因此可提供更强的安全性。

令牌请求参数是表单编码的:

  • grant_type设置为authorization_code。
  • 代码从步骤1获得的代码。
  • redirect_uri重复步骤1中的回调URI。

成功时,授权服务器将返回具有已颁发访问令牌的JSON对象:

HTTP/1.1 200 OK

Content-Type: application/json

Cache-Control: no-store

Pragma: no-cache

{ "access_token" : "SlAV32hkKG",

"token_type" : "Bearer",

"expires_in" : 3600,

"scope" : "myapi-read myapi-write"

}


expires_in参数通知客户端访问令牌有效的秒数。范围参数是令牌实际具有的功能,因为某些最初请求的范围值可能已被拒绝,或者其他未明确请求的范围值被授予。

JSON对象可以包含可选的刷新令牌,该令牌允许客户端从授权服务器获取新的访问令牌,而无需重复代码流。

4.客户端如何使用令牌访问受保护资源?


使用令牌访问资源服务器(例如Web API)非常简单。 OAuth 2.0中的访问令牌通常是类型承载,这意味着客户端只需要为每个请求传递令牌。 HTTP Authorization标头是推荐的方法。

GET /resource/v1 HTTP/1.1

Host: api.example.com

Authorization: Bearer oab3thieWohyai0eoxibaequ0Owae9oh


如果资源服务器确定令牌有效且未过期,则它将继续为请求提供服务。

否则,它将在HTTP WWW-Authenticate响应头中返回适当的错误。

无效或过期令牌的示例错误:

HTTP/1.1 401 Unauthorized

WWW-Authenticate: Bearer realm="api.example.com",

error="invalid_token",

error_description="The access token is invalid or expired"


如果客户端收到过去工作的访问令牌的invalid_token错误,则表明它必须从授权服务器请求新的错误。

承载令牌(bearer tokens)的使用在RFC 6750中指定。

请记住,令牌的承载性质意味着拥有它的任何人都可以访问资源服务器。因此,必须保护承载令牌 - 首先,通过将它们保存在安全的客户端存储中,然后在传输中,通过TLS提交它们。发行短期令牌可以减少令牌泄漏的潜在风险。

5.如何使用令牌保护资源服务器?


要清除提交的请求,资源服务器需要验证令牌。验证确保以下内容:

  1. 访问令牌已由授权服务器发出。
  2. 令牌尚未过期。
  3. 其范围涵盖了请求。

如何完成取决于访问令牌的特定实现,该实现由授权服务器确定。更多内容将在下一章中介绍。

所需的令牌验证逻辑可以很容易地从底层资源中抽象出来,或者改装到现有资源上。可以使用反向HTTP代理或API网关来实现该目的。

最受欢迎的Web服务器和框架(例如Apache httpd和Spring)提供某种模块来验证使用承载访问令牌保护的传入请求。在成功验证后,可以向底层资源提供所选的有用令牌属性,例如最终用户的身份。这又是一个实施问题。

6.访问令牌


OAuth 2.0框架没有规定访问令牌的特定实施例。 这个决定留给实现者的理由很充分:对于客户端,令牌只是一个不透明的字符串; 它们的验证是授权服务器和资源服务器之间的问题,并且由于它们通常属于同一个提供者,因此没有足够的需求来指定标准令牌格式。

从根本上说,有两种类型的持票人令牌:

Identifier-based Self-contained
The token represents a hard-to-guess string which is a key to a record in the authorisation server's database. A resource server validates such a token by making a call to the authorisation server's introspection endpoint. The token encodes the entire authorisation in itself and is cryptographically protected against tampering. JSON Web Token (JWT) has become the defacto standard for self-contained tokens.

Pros / cons of identifier-based tokens:

  • If needed, a client's or user's access tokens can be revoked with immediate effect.
  • Token validation requires a network call which may increase the time to serve requests.
  • May be difficult to scale with distributed applications.

Pros / cons of self-contained tokens:

  • Tokens can be validated on the spot, by checking their signature and then extracting their payload.
  • Easy to scale with distributed applications.
  • The revocation of access takes effect when the issued tokens expire.

7.授权服务器


授权服务器负责为其域中的受保护资源发出访问令牌。

OAuth使服务器实施者可以自由地确定最终用户的身份验证方式以及实际授权的执行方式。 Connect2id服务器充分利用了这一点,并提供了一个灵活的Web API,用于插入任何类型的身份验证因素以及逻辑,以确定已发布的访问令牌的范围。

7.1最终用户认证


授权服务器可以例如实现密码和基于风险的认证的组合,其中当客户端请求高价值资源或交易的访问令牌时,需要诸如U2F的第二因素。

用户的认证也可以委托给外部提供者,例如通过给用户选择流行的社交登录。也可以利用自发的身份。

成功进行身份验证后,通常会建立一个会话,以便为用户提供单点登录(对于涉及浏览器的OAuth授权或流量)的好处。

可以要求用户重新认证他们的浏览器的IP地址是否改变,或者如果令牌范围要求更大确定合法用户存在。这再次受制于具体的服务器策略。

7.2授权


与最终用户身份验证一样,授权过程和确定发布的令牌接收的范围是特定于实现的。

发布用于访问最终用户数据和其他资源的令牌的授权服务器通常呈现同意表,其中最终用户可以决定授予哪些范围以及哪些范围不授予请求应用程序。

公司中的授权服务器将查阅策略,该策略考虑员工的状态和角色以确定令牌范围,跳过任何与同意相关的交互。客户的信任级别,例如内部应用程序与外部应用程序,也可能是一个因素。

7.3客户端认证


OAuth定义了两种类型的客户端,具体取决于它们使用授权服务器进行安全身份验证的能力:

机密 - 可以将其凭据与最终用户和其他实体保密的客户端。在Web服务器上执行的Web应用程序可以是此类客户端。

公共 - 在用户的设备上,用户的浏览器或类似环境中执行的客户端,可以相对轻松地提取客户端中存储的任何凭据。

无论其类型如何,所有客户端都会获得授权服务器分配的唯一client_id。

到目前为止,已指定了六种不同的客户端身份验证方法,授权服务器可以实现其中任何一种:

Method Description
client_secret_basic Essentially HTTP basic authentication with a shared secret. The most widely implemented because of its simplicity, but also with the weakest security properties.
client_secret_post A variant of basic authentication where the credentials are passed as form parameters instead of in the Authorization header.
client_secret_jwt The client authenticates with a JSON Web Token (JWT) secured with an HMAC using the client secret as key. Prevents leakage of the secret and limits the time-window for replay if the request is accidentally sent over unsecured HTTP.
private_key_jwt Another JWT-based authentication method, but using a private key, such as RSA or EC, which public part is registered with the authorisation server. Private key authentication limits the proliferation of secrets and also provides a non-repudiation property.
tls_client_auth The client authenticates with a client X.509 certificateissued from a CA authority trusted by the authorisation server.
self_signed_tls_client_auth The client authenticates with a self-signed client X.509 certificate. Has similar properties as the private key JWT method.

 

7.4。 授权服务器端点

Core endpoints Optional endpoints

7.4.1授权端点


这是服务器端点,其中对最终用户进行身份验证,并在授权代码中授予请求客户端授权和隐式流(授权)。剩余的OAuth 2.0授权不涉及此端点,而是令牌令牌。

这也是通过前端通道(浏览器)和用户与服务器交互的唯一标准端点。

7.4.2令牌端点


令牌端点允许客户端为访问令牌交换有效授权,例如从授权端点获得的代码。

还可以发布刷新令牌,以允许客户端在其到期时获得新的访问令牌,而不必重新提交原始授权授权的新实例,例如代码或资源所有者密码凭证。这样做的目的是最小化最终用户与授权服务器的交互量,从而更好地体验整体体验。

如果客户端是机密的,则需要在令牌端点进行身份验证。

7.4.3可选端点


授权服务器可以具有以下附加端点:

服务器元数据 - 列出服务器端点URL及其支持的OAuth 2.0功能的JSON文档。客户端可以使用此信息配置对服务器的请求。

服务器JWK集 - 带有服务器公钥(通常为RSA或EC)的JSON文档,采用JSON Web Key(JWK)格式。这些密钥可用于保护发布的JWT编码的访问令牌和其他对象。

客户端注册 - 用于向授权服务器注册客户端的RESTful Web API。注册可能受到保护(需要预先授权)或开放(公共)。

令牌内省 - 用于让资源服务器验证基于标识符的访问令牌。也可用于验证自包含访问令牌。

令牌撤销 - 用于让客户端通知授权服务器不再需要先前获得的刷新或访问令牌。请注意,此端点不用于撤消对最终用户或客户端的访问;这将需要一个自定义API。

8.常见问题


8.1 OpenID Connect如何与OAuth 2.0相关?


OpenID Connect是用于验证最终用户的具体协议,在OAuth 2.0框架之上设计。因此,OpenID Connect通常也称为OAuth 2.0的配置文件。

OpenID Connect引入了一个新令牌,称为ID令牌,用于编码最终用户的身份。 ID令牌通过现有的标准OAuth 2.0流程提供。

仍然使用访问令牌。它有助于从OpenID提供程序的UserInfo端点检索同意的配置文件详细信息(称为声明或属性)。

8.2还存在哪些其他OAuth 2.0配置文件?


社区正在开发除OpenID Connect之外的其他具体配置文件,由专家仔细审查,为特定行业或应用程序域提供基于令牌的安全性:

  • FAPI  - 用于开放式银行和PSD2实施的金融级应用程序的高安全性配置文件。
  • HEART  - 允许个人控制对其健康相关数据的访问的配置文件。
  • MODRNA  - 适用于向依赖方提供身份服务的移动网络运营商。
  • EAP  - 集成令牌绑定和FIDO的安全和隐私配置文件。
  • iGOV  - 用于在全球范围内通过公共部门服务对同意数据进行身份验证和共享。

 

原文:https://connect2id.com/learn/oauth-2

本文:http://pub.intelligentx.net/node/467

讨论:请加入知识星球或者小红圈【首席架构师圈】

Article
知识星球
 
微信公众号
 
视频号