What is the purpose of the implicit grant authorization type in OAuth 2?
我不知道我是否只是有一些盲点或者什么,但是我已经阅读了很多次OAuth2规范并仔细阅读了邮件列表存档,我还没有找到一个很好的解释,为什么开发了用于获取访问令牌的隐式授权流。与授权代码授予相比,它似乎只是放弃了客户端身份验证,原因并不十分令人信服。如何"针对使用脚本语言在浏览器中实现的客户端进行优化"(引用规范)?
两个流的开头相同(来源:http://tools.ietf.org/html/draft-ietf-oauth-v2-22):
- 重定向URI包括授权代码(授权代码流)
- 重定向URI在URI片段中包含访问令牌(隐式流)
这里是水流分开的地方。在这两种情况下,此时的重定向URI都指向客户机承载的某个端点:
- 在授权代码流中,当用户代理使用URI中的授权代码访问该端点时,该端点的代码会交换授权代码及其客户端凭据,以获取访问令牌,然后根据需要使用该令牌。例如,它可以将其写入页面上的脚本可以访问的网页。
- 隐式流跳过了这个客户机身份验证步骤,只是用客户机脚本加载了一个网页。这里有一个巧妙的技巧,即URL片段可以防止访问令牌被传递过多,但最终结果基本相同:客户机托管的站点提供一个页面,其中包含一些可以获取访问令牌的脚本。
因此我的问题是:跳过客户机身份验证步骤在这里获得了什么?
以下是我的想法:
授权代码流中的auth code+token的目的是,令牌和客户机机密永远不会向资源所有者公开,因为它们将服务器传输到服务器。
另一方面,隐式授权流用于完全使用JavaScript实现并在资源所有者的浏览器中运行的客户机。使用此流不需要任何服务器端代码。然后,如果在资源所有者的浏览器中发生任何事情,那么再发出auth code&client secret就没有意义了,因为token&client secret仍将与资源所有者共享。包括auth code&client secret只会使流程更加复杂,而不会增加任何真正的安全性。
所以关于"得到了什么?"是"简单"。
它的存在是为了安全,而不是为了简单。
您应该考虑用户代理和客户机之间的区别:
用户代理是用户("资源所有者")与系统其他部分(身份验证服务器和资源服务器)通信的软件。
客户端是要访问资源服务器上用户资源的软件。
在分离用户代理和客户机的情况下,授权代码授予是有意义的。例如,用户使用Web浏览器(用户代理)在Kickstarter上使用其Facebook帐户登录。在这种情况下,客户机是Kickstarter的服务器之一,它处理用户登录。此服务器从Facebook获取访问令牌和刷新令牌。因此,这种类型的客户机被认为是"安全的",由于访问受限,令牌可以被保存,Kickstarter可以访问用户的资源,甚至刷新访问令牌,而无需用户交互。
如果用户代理和客户机是耦合的(例如本地移动应用程序、javascript应用程序),则可以应用隐式授权工作流。它依赖于资源所有者的存在(用于输入凭据),不支持刷新令牌。如果此客户端存储访问令牌以供以后使用,那么这将是一个安全问题,因为客户端的其他应用程序或用户可以轻松提取令牌。缺少刷新令牌是另外一个提示,即此方法不是为在缺少用户的情况下访问用户资源而设计的。
通常的解释是,使用JavaScript客户机时,隐式授权更容易实现。但我认为这是错误的看待方式。如果您使用的是通过xmlhttprequest直接请求受保护资源的javascript客户机,则隐式授权是您唯一的选择,尽管它不太安全。*
授权代码授予提供了额外的安全性,但它仅在Web服务器请求受保护的资源时才起作用。由于Web服务器可以存储访问令牌,因此访问令牌暴露于Internet的风险较小,并且您可以发布一个持续时间较长的令牌。由于Web服务器是可信的,所以可以给它一个"刷新令牌",以便在旧的访问令牌到期时获得新的访问令牌。
但是——这是一个很容易忽略的点——授权代码流的安全性只有在Web服务器受会话保护的情况下才能工作,会话是通过用户身份验证(登录)建立的。如果没有会话,不受信任的用户就可以使用客户机ID向Web服务器发出请求,这与用户拥有访问令牌的情况相同。添加会话意味着只有经过身份验证的用户才能访问受保护的资源。客户端_ID只是JS webapp的"身份",而不是所述webapp的身份验证。
它还意味着您可以在OAuth令牌过期之前结束会话。没有标准的方法可以使访问令牌失效。但是,如果您的会话过期,那么访问令牌是无用的,因为除了Web服务器,没有人知道它。如果不受信任的用户获得了对会话密钥的访问权,那么只要会话有效,他们就只能访问受保护的资源。
如果没有Web服务器,则必须使用隐式授权。但这意味着访问令牌暴露在互联网上。如果不受信任的用户获得了对它的访问权,他们可以使用它直到它到期。这意味着他们访问它的时间要比授权码授权的时间长。因此,您可能需要考虑使令牌更快过期,并避免授予对更敏感资源的访问权。
*编辑:最近,人们建议您避免使用隐式授权,即使是在没有服务器的Web应用上。相反,您可以使用配置为空秘密的授权代码授予,以及pkce。授权代码授权可以避免将访问令牌存储在浏览器历史记录中,并且pkce可以避免在有人劫持重定向URL以窃取授权代码时暴露它。在这种情况下,您需要服务器避免返回刷新令牌,因为您的客户机可能无法安全地存储它。它应该发布一个具有上述限制的访问令牌。
归根结底,如果用户运行的是基于浏览器的或"公共"(javascript)Web应用程序,而没有服务器端组件,那么用户将隐式信任该应用程序(以及运行该应用程序的浏览器,可能是其他基于浏览器的应用程序…)。
没有第三方远程服务器,只有资源服务器。授权代码没有好处,因为除了代表用户的浏览器之外,没有其他代理。出于同样的原因,对客户端凭据没有好处。(任何客户端都可以尝试使用此流。)
然而,安全影响是重大的。从http://tools.ietf.org/html/rfc6749第10.3节:
When using the implicit grant type, the access token is transmitted in
the URI fragment, which can expose it to unauthorized parties.
号
从http://tools.ietf.org/html/rfc6749第10.16节:
A resource owner may willingly delegate access to a resource by
granting an access token to an attacker's malicious client. This may
be due to phishing or some other pretext...
号
我不确定我是否正确理解了答案和丹的评论。在我看来,答案说明了一些事实是正确的,但它确实指出了OP所要求的。如果我理解正确,隐式授权流的主要优点是像JS应用程序这样的客户机(例如chrome扩展)不必公开客户机秘密。
丹·塔弗林说:
...in the authorization code flow the resource owner never needs to see the access token, whereas in javascript clients that's unavoidable. Client secret could still be kept from javascript clients using authorization code flow, however..
号
也许我误解了您的意思,但是客户机(在本例中是JS应用程序)必须在授权代码流中将客户机凭据(客户机密钥和机密)传递给资源服务器,对吗?客户端机密不能"保留在JS之外"。
虽然隐式授权旨在支持无法保护客户端机密的应用程序,包括客户端JavaScript应用程序,但一些提供程序正在使用不带客户端机密的授权代码实现替代方案。OAuth 2.0 IETF RFC-6749于2012年发布,目前的一些建议最近的讨论来自2017年。
有关IETF OAuth邮件列表的2017年讨论可从以下实施者处获得:
- 红帽:https://www.ietf.org/…/oauth/current/msg16966.html
- 德国电信:https://www.ietf.org/…/oauth/current/msg16968.html
- 智能健康IT:https://www.ietf.org/…/oauth/current/msg16967.html
阅读更多信息:
- https://aaronparecki.com/oauth-2-简化/
- https://aaronparecki.com/oauth-2-simpled/单页应用程序
Implicit was previously recommended for clients without a secret, but has been superseded by using the Authorization Code grant with no secret.
...
Previously, it was recommended that browser-based apps use the"Implicit" flow, which returns an access token immediately and does not have a token exchange step. In the time since the spec was originally written, the industry best practice has changed to recommend that the authorization code flow be used without the client secret. This provides more opportunities to create a secure flow, such as using the state parameter. References: Redhat, Deutsche Telekom, Smart Health IT.
号
对于移动应用程序,这里还提到了从隐式授权转移到不带客户端机密的授权代码:
- https://aaronparecki.com/oauth-2-simpled/移动应用程序
在隐式流程中,如果用户的浏览器已损坏(邪恶的扩展名/病毒),则损坏会访问用户的资源,并可能造成不良后果。
在身份验证流中,由于不知道客户端机密,因此无法进行损坏。
除了其他答案外,还必须认识到隐式配置文件只允许前端通道流,而不是需要回调授权服务器的授权代码流;这在OpenID Connect中很明显,它是一个构建在auth 2.0之上的SSO协议,其中隐式流类似于他非常流行SAML后期绑定,授权代码流类似于部署不那么广泛的SAML工件绑定。
https://tools.ietf.org/html/rfc6749第8页
Implicit
The implicit grant is a simplified authorization code flow
optimized for clients implemented in a browser using a scripting
language such as JavaScript. In the implicit flow, instead of
issuing the client an authorization code, the client is issued an
access token directly (as the result of the resource owner
authorization). The grant type is implicit, as no intermediate
credentials (such as an authorization code) are issued (and later
used to obtain an access token).When issuing an access token during the implicit grant flow, the
authorization server does not authenticate the client. In some
cases, the client identity can be verified via the redirection URI
used to deliver the access token to the client. The access token may
be exposed to the resource owner or other applications with access to
the resource owner's user-agent.Implicit grants improve the responsiveness and efficiency of some
clients (such as a client implemented as an in-browser application),
since it reduces the number of round trips required to obtain an
access token.
号
我想凯恩回答这个问题的时候,他说,"因为同样的原因,对客户资格没有好处。(任何客户端都可以尝试使用此流。)"还应考虑隐式流的重定向u uri可能是"localhost"--对于隐式流,不会从授权服务器进行回调。由于无法预先信任客户端,因此用户必须批准发布用户声明。
隐式授权允许使用
如果这不是一个问题,并且没有与授权服务器相关的其他问题是不灵活的(例如,出于某种原因,刷新令牌不是可选的),那么根据最近的行业趋势和至少是官方草案的这个(当前的)实例,授权代码流是首选的,即使对于公共客户端也是如此。
历史上,实现隐式流还有其他原因,但目前看来,这些原因被授权代码授予提供的安全优势所抵消,包括:
- 通过后台通道为机密客户端交付和使用令牌的选项
- 不在浏览器历史记录中公开公用客户端的令牌
- 在为"所有类型的OAuth客户机"颁发令牌之前中断未经授权的流-使用pkce