本文以一种简化的格式描述OAuth 2.0 ,以帮助开发人员和服务提供者实现该协议。
The OAuth 2 spec(规范) 读起来让人有点困惑,我写这篇文章是为了帮助用简化的格式来描述术语。核心规范将许多决策留给实现者,通常是基于实现的安全权衡。而不是描述所有需要成功实现OAuth 2的可能的决策,这篇文章做出了适合大多数实现的决策。
注意:这篇文章是根据OAuth 2.0的当前最佳实践,从2012年的版本得到了更新的。原版本可以在这里找到。here.
Table of Contents (目录)
- Roles: Applications, APIs and Users
- Creating an App
-
Authorization: Obtaining an access token 授权,获取一个令牌
- Web Server Apps
- Single-Page Apps 单页面应用程序
- Mobile Apps
- Others
- Making Authenticated Requests 制作身份验证的请求
- Differences from OAuth 1.0 区别OAuth1.0
- Authentication and Signatures 身份验证和签名
- User Experience and Alternative Authorization Flows 用户体验和可选授权流
- Performance at Scale 大规模集群的性能
- Resources
Roles (角色)
The Third-Party Application: "Client" (第三方应用程序:“客户端”)
客户端是试图访问用户账户的应用程序。它需要得到用户的许可才能做到这一功能。
The API: "Resource Server" (API:"资源服务器")
资源服务器是用于访问用户信息的API服务器。
The Authorization Server(授权服务器)
这是提供用户批准或拒绝请求的接口服务器。在较小的规模中,这可能是与API资源服务器相同的服务器,但更大规模的部署通常会将其作为单独的组件构建。
The User: "Resource Owner"(用户:“资源所有者”)
资源所有者是能够访问他们部分账户信息的人。
Creating an App(创建一个应用程序)
在开始OAuth流程之前,你必须先注册一个新的应用程序。在注册一个新的应用程序的时候,你通常会注册一些基本信息,比如应用程序名称,网站,标识等等。此外,您必须注册一个重定向URL,以便将用户重定向到web服务器,基于浏览器或移动应用程序。
Redirect URIs (重定向的URL)
该服务只会将用户重定向到一个已注册的URL,这有助于防止一些攻击。任何HTTP重定向URL都必须使用TLS(安全传输层协议)安全保护,因此服务器将只重定向到以"https"开头的URL。这样可以防止令牌(tokens)在授权过程中被拦截,本地应用程序可以注册一个针对它的重定向URL解决方案。它看起来像:demoapp://redirect.
Client ID and Secret (客户端ID 和 密钥)
在注册了你的应用之后,你将收到一个客户ID和一个客户的密钥。客户ID被认为是公共信息,用于构建登录URL,或者包含在网页上的JavaScript源代码中。客户的密钥必须保密,如果一个被部署的应用不能保守密钥,比如单页javascript应用或者原生应用,然后,这个密钥就不会被使用了,最理想的情况是,服务不应该首先对这些类型的应用发布密钥。
Authorization (授权)
OAuth 2的第一步是获得用户的授权,对于基于浏览器或移动的应用程序来说,这通常是通过向用户显示服务器提供的接口来实现的。
OAuth 2为不同的用例提供了几种“授权类型”。授权类型定义是:
Authorization Code for apps running on a web server, browser-based and mobile apps
(授权码:对于在web服务器上运行的应用程序,基于浏览器和移动用友程序)Password for logging in with a username and password
(密码:使用用户名和密码登录的密码)Client credentials for application access
(应用程序访问的客户凭据)Implicit was previously recommended for clients without a secret, but has been superceded by using the Authorization Code grant with no secret.
(隐式之前推荐给没有密钥的客户,但是通过使用授权代码授权,没有任何密钥。已经被取代)
下面将详细描述每个用例:
Web Server Apps(网络服务器应用程序)
在处理OAuth服务器时,Web服务器应用程序是您遇到的最常见的应用程序类型。Web应用程序是用服务端语言写的,并在服务器上运行,而应用程序的源代码在公共场合是不可用的。这意味着应用程序可以在与授权服务器通信时使用它的客户端机密,这可以帮助避免一些攻击向量。
Authorization
创建一个“登录”链接,将用户发送到:
https://oauth2server.com/auth?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=photos&state=1234zyx
- code - Indicates that your server expects to receive an authorization code (表明您的服务器期望收到授权代码)
- client_id - The client ID you received when you first created the application (第一次创建应用程序时接收到的客户ID)
- redirect_uri - Indicates the URI to return the user to after authorization is complete (表示在授权完成之后将URL返回给用户)
- scope - One or more scope values indicating which parts of the user's account you wish to access (一个或者多个范围值:指示您希望访问的用户账户的哪些部分)
- state - A random string generated by your application, which you'll verify later (由应用程序生成的随机字符串,稍后将验证。)
用户看到授权提示符:
如果用户单击“允许”,该服务将使用一个auth(授权)码将用户重定向到您的站点。
https://oauth2client.com/cb?code=AUTH_CODE_HERE&state=1234zyx
-
code - The server returns the authorization code in the query string
(服务器返回查询字符串中的授权代码) -
state - The server returns the same state value that you passed
(服务器返回您通过的相同的状态值)
您应该首先比较这个状态值,以确保它与您开始时的值相匹配。通常可以将状态值存储在cookie或者会话中。然后在用户返回时进行比较。这将确保您的重定向端点不能被欺骗来尝试交换任意的授权代码。
Token Exchange(令牌交换)
您的服务器交换用于访问令牌的身份验证码(授权码):
POST https://api.oauth2server.com/token
grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=REDIRECT_URI&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
grant_type=authorization_code - The grant type for this flow is authorization_code
(该流程的授权类型是authorization_code )code=AUTH_CODE_HERE - This is the code you received in the query string
(这是在查询字符串中接收到的代码)redirect_uri=REDIRECT_URI - Must be identical to the redirect URI provided in the original link
(必须与原始链接中提供的重定向URL相同)client_id=CLIENT_ID - The client ID you received when you first created the application
(你收到你第一次创建应用程序时的客户端ID)client_secret=CLIENT_SECRET - Since this request is made from server-side code, the secret is included
(由于这个请求时由服务端代码完成的,所以包含了这个密钥)
服务器以访问令牌和过期时间来应答。
{
"access_token":"RsT5OjbzRn430zqMLgV3Ia",
"expires_in":3600
}
或者如果出现了错误:
{
"error":"invalid_request"
}
安全性:注意,服务必须要求应用程序预先注册它们的重定向URL。
Single-Page Apps(单页面应用程序)
单页面应用程序(或基于浏览器的应用程序)在从网页加载源代码后完全在浏览器运行。因为整个源代码都可以在浏览器中使用,他们不能保持客户密钥的机密性。所以这个密钥是不被使用的。该流正好与上面的授权码流完全相同。但在最后一步,在不使用客户端密钥的情况下,将授权代码交换访问令牌。
注意:以前,推荐使用基于浏览器的应用程序使用“隐式”流“它立即返回一个访问令牌,并且没有令牌交换步骤。在最初编写规范的时候,行业最佳实践已经改变,建议在不使用客户端密钥的情况下使用授权代码流。这位创建安全流提供了更多的机会,例如使用状态参数。引用:Redhat, Deutsche Telekom,Smart Health IT.
Authorization (授权)
创建一个”登录“链接,将用户发送到:
https://oauth2server.com/auth?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=photos&state=1234zyx
code - Indicates that your server expects to receive an authorization code
(表明您的服务器期望收到授权码)client_id - The client ID you received when you first created the application
(第一次创建应用程序时接收到的客户端ID)redirect_uri - Indicates the URI to return the user to after authorization is complete
(表示在授权完成之后将URL返回给用户.)scope - One or more scope values indicating which parts of the user's account you wish to access
(一个或多个范围值指定该用户账户的哪些部分你想要访问的)state - A random string generated by your application, which you'll verify later
(由应用程序生成的随机字符串,稍后将验证。)
用户看到授权提示符:
如果用户单击”允许“,该服务将使用一个auth码将用户重定向到您的站点。
https://oauth2client.com/cb?code=AUTH_CODE_HERE&state=1234zyx
code - The server returns the authorization code in the query string
(服务器返回查询字符串中的授权代码)state - The server returns the same state value that you passed
(服务器返回您通过的相同的状态值)
您应该首先比较这个状态值,以确保它与开始时的值相匹配。通常可以将状态值存储在cookie中,然后在用户返回时进行比较。这将确保您的重定向端点不能被欺骗来尝试交换任意的授权代码。
Token Exchange(令牌交换)
POST https://api.oauth2server.com/token
grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=REDIRECT_URI&
client_id=CLIENT_ID