183

OAuth 2.0 有多个工作流程。关于这两者,我有几个问题。

  1. 授权码流程- 用户从客户端应用程序登录,授权服务器向应用程序返回一个授权码。然后,该应用程序将授权代码交换为访问令牌。
  2. 隐式授权流程- 用户从客户端应用程序登录,授权服务器直接向客户端应用程序发出访问令牌。

就安全性而言,这两种方法有什么区别?哪个更安全,为什么?

当服务器可以直接发出访问令牌时,我看不出为什么在一个工作流程中添加了一个额外的步骤(交换令牌的授权代码)。

不同的网站说,当客户端应用程序可以保持凭据安全时,会使用授权代码流。为什么?

4

9 回答 9

222

access_token就是您需要调用受保护的资源(API)。在授权码流程中有两个步骤来获取它:

  1. 用户必须进行身份验证并将其返回code给 API 使用者(称为“客户端”)。
  2. API 的“客户端”(通常是您的 Web 服务器)将code在 #1 中获得的信息交换为 a ,并access_token使用 aclient_idclient_secret
  3. 然后它可以使用access_token.

因此,有一个双重检查:拥有通过 API 显示的资源的用户和使用 API 的客户端(例如 Web 应用程序)。两者都经过验证以授予访问权限。请注意此处 OAuth 的“授权”性质:用户将其资源的访问权限(通过code身份验证后返回)授予应用程序,应用程序获取的是 an access_token,并代表用户调用。

在隐式流程中,省略了步骤 2。所以在用户认证之后,access_token直接返回一个,你可以使用它来访问资源。API 不知道谁在调用该 API。任何人都access_token可以,而在前面的示例中,只有 Web 应用程序可以(它的内部结构通常任何人都无法访问)。

隐式流通常用于不推荐存储的场景client idclient secret例如设备,尽管很多人都这样做)。这就是免责声明的意思。人们可以访问客户端代码,因此可以获得凭据并假装成为资源客户端。在隐式流中,所有数据都是易失的,应用程序中没有存储任何内容。

于 2013-05-02T15:30:27.817 回答
61

我将在这里添加一些我认为在上述答案中没有明确说明的内容:

  • Authorization-Code-Flow 允许最终的访问令牌永远不会到达并且永远不会存储在带有 browser/app 的机器上。使用浏览器/应用程序将临时授权代码提供给机器,然后将其发送到服务器。然后服务器可以用一个完整的访问令牌交换它并访问 API 等。使用浏览器的用户只能通过带有令牌的服务器访问 API。
  • 隐式流只能涉及两方,最终访问令牌与浏览器/应用程序一起存储在客户端上。如果此浏览器/应用程序受到威胁,他们的身份验证令牌也会受到威胁,这可能很危险。

tl;如果您不信任用户机器持有令牌但您确实信任自己的服务器,请不要使用隐式流程。

于 2014-08-08T10:31:26.720 回答
16

两者的区别在于:

  1. 在隐式流中,令牌通过带有“#”符号的重定向 URL 直接返回,这主要用于 javascript 客户端或本身没有服务器端的移动应用程序,并且客户端在某些实现中不需要提供其秘密.

  2. 在授权代码流中,代码返回“?” 要被服务器端读取,那么服务器端这次必须向令牌 url 提供客户端密码,以从授权服务器获取令牌作为 json 对象。它用于如果您有可以处理此问题的应用程序服务器并将用户令牌与他/她的个人资料一起存储在他自己的系统上,并且主要用于常见的移动应用程序。

所以这取决于您的客户端应用程序的性质,哪个更安全的“授权代码”因为它请求客户端上的秘密并且令牌可以在授权服务器和客户端应用程序之间以非常安全的连接发送,并且授权提供者可以限制某些客户端仅使用“授权码”并禁止隐式

于 2013-05-02T09:22:51.767 回答
6

哪个更安全,为什么?

它们都是安全的,这取决于您使用它的环境。

当服务器可以直接发出访问令牌时,我看不出为什么在一个工作流程中添加了一个额外的步骤(交换令牌的授权代码)。

很简单。您的客户端不安全。让我们详细看看它。

考虑您正在开发一个针对 的应用程序Instagram API,因此您注册您的应用程序Instagram并定义API's您需要的应​​用程序。Instagram将为您提供client_idclient_secrect

在您的网站上,您设置了一个链接,上面写着。“来使用我的应用程序”。单击它,您的 Web 应用程序应该Instagram API.

FirstInstagram Authentication Server使用以下参数发送请求。

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

您不发送client_secret,您无法信任客户端(尝试使用您的应用程序的用户和/或他的浏览器)。客户端可以看到 url 或 java 脚本并client_secrect轻松找到您的。这就是为什么你需要另一个步骤。

您收到一个codestate。这里codetemporary并且没有保存在任何地方。

然后你second打电话给Instagram API(从你的服务器)

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

由于调用是从我们的服务器发出的,我们可以安全地使用client_secret(这表明我们是谁),code这表明用户已授权client_id使用该资源。

作为回应,我们将有access_token

于 2018-08-19T07:24:04.907 回答
5

隐式授权类似于授权码授权,但有两个明显的区别。

它旨在用于基于用户代理的客户端(例如单页 Web 应用程序),因为所有应用程序代码和存储都易于访问,因此无法保密客户端。

其次,授权服务器返回一个访问令牌,而不是授权服务器返回一个用于交换访问令牌的授权代码。

请在此处找到详细信息 http://oauth2.thephpleague.com/authorization-server/which-grant/

于 2016-04-25T20:37:38.373 回答
3

让我总结一下我从上面的答案中学到的要点,并添加一些我自己的理解。

授权码流程!!!

  • 如果您有一个充当 OAuth 客户端的 Web 应用程序服务器
  • 如果您想长期访问
  • 如果您想离线访问数据
  • 当您对应用程序进行的 api 调用负责时
  • 如果您不想泄露您的 OAuth 令牌
  • 如果您不希望您的应用程序在每次需要访问数据时都通过授权流程运行。注意:隐式授予流程不接受刷新令牌,因此如果授权服务器定期使访问令牌过期,您的应用程序将需要在需要访问时通过授权流程运行。

隐式赠款流程!!!

  • 当您没有 Web 应用程序服务器充当 OAuth 客户端时
  • 如果您不需要长期访问,即只需要临时访问数据。
  • 如果您信任运行应用程序的浏览器,并且访问令牌会泄漏给不受信任的用户的担忧有限。
于 2017-01-13T15:38:57.717 回答
1

从实际的角度来看(我的理解),拥有 Authz 代码流的主要原因是:

  1. 支持刷新令牌(应用程序代表用户长期访问),隐式不支持:参考:https ://www.rfc-editor.org/rfc/rfc6749#section-4.2
  2. 支持同意页面,这是资源所有者可以控制提供哪些访问权限的地方(您在 google 中看到的权限/授权页面类型)。隐式中不存在相同的。见章节:https ://www.rfc-editor.org/rfc/rfc6749#section-4.1 ,点(B)

“授权服务器(通过用户代理)对资源所有者进行身份验证,并确定资源所有者是授予还是拒绝客户端的访问请求”

除此之外,使用刷新令牌,应用程序可以长期访问用户数据。

于 2016-12-06T07:20:11.217 回答
0

似乎有两个关键点,到目前为止没有讨论,这解释了为什么 Authorization Code Grant Type 中的绕道增加了安全性。

小故事:Authorization Code Grant Type 保留了浏览器历史中的敏感信息,token 的传输只依赖于授权服务器的 HTTPS 保护。

更长的版本:

在下文中,我将坚持使用RFC中定义的 OAuth 2 术语(快速阅读):资源服务器客户端授权服务器资源所有者

想象一下,您希望某个第三方应用程序(= 客户端)访问您的 Google 帐户(= 资源服务器)的某些数据。假设 Google 使用 OAuth 2。您是 Google 帐户的资源所有者,但现在您在操作第三方应用程序。

首先,客户端打开浏览器,将您发送到 Google 授权服务器的安全 URL。然后您批准访问请求,授权服务器将您发送回客户端先前提供的重定向 URL,并在查询字符串中包含授权代码。现在来说两个关键点:

  1. 此重定向的 URL 最终出现在浏览器历史记录中。所以我们不想要一个长寿的、直接可用的访问令牌。短暂的授权码在历史上的危险性较小。请注意,隐式授予类型确实将令牌放入历史记录中。
  2. 此重定向的安全性取决于客户端的 HTTPS 证书,而不是 Google 的证书。因此我们将客户端的传输安全性作为额外的攻击向量(为了避免这种情况,客户端必须是非 JavaScript 的。否则我们可以通过片段 URL 传输授权代码,代码不会通过网络。可能是为什么使用片段 URL 的隐式授权类型曾经被推荐给 JavaScript 客户端的原因,尽管现在不再如此。)

使用 Authorization Code Grant Type,最终通过客户端调用授权服务器获得令牌,传输安全性只依赖于授权服务器,不依赖于客户端。

于 2019-11-02T20:51:41.000 回答
0

不应再使用隐式授权,有关详细信息,请参阅 IETF 当前最佳实践。https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-18#section-2.1.2

作为替代方案,使用带有响应类型代码的流;对于无法安全存储客户端凭据的客户端,您应该选择使用 PKCE 流的授权代码。

于 2021-11-27T11:45:19.633 回答