隐式授权授权types在OAuth 2中的用途是什么?

我不知道我是否有某种盲点或什么,但是我已经多次阅读了OAuth 2规范,并仔细阅读了邮件列表的档案,我还没有find一个很好的解释为什么隐式授权已经开发出获取访问令牌的stream程。 与授权代码授权相比,它似乎只是放弃了客户端authentication,没有任何令人信服的理由。 这是如何“为使用脚本语言在浏览器中实现的客户端进行了优化”(引用规范)?

两个stream程都是从相同的(来源: http : //tools.ietf.org/html/draft-ietf-oauth-v2-22 ):

  1. 客户端通过将资源所有者的用户代理指向授权端点来启动stream程。
  2. 授权服务器(通过用户代理)authentication资源所有者,并确定资源所有者是否授予或拒绝客户端的访问请求。
  3. 假设资源所有者授予访问权限,授权服务器使用之前(在请求中或在客户端注册期间)提供的redirectURI将用户代理redirect回客户端。
    • redirectURI包括授权码(授权码stream)
    • redirectURI包括URI片段中的访问令牌(隐式stream)

这是stream量分裂的地方。 在这两种情况下,redirectURI都是由客户端托pipe的一些端点:

  • 在授权代码stream中,当用户代理使用URI中的授权代码击中该端点时,该端点上的代码将授权代码与其客户端凭证一起交换访问令牌,然后根据需要使用该令牌。 例如,它可以将其写入页面上的脚本可以访问的网页中。
  • 隐式stream程完全跳过了这个客户端authentication步骤,只是用客户端脚本加载一个网页。 这里有一个可爱的技巧,URL片段使得访问令牌不被传递太多,但最终结果基本相同:客户端托pipe的站点提供了一个页面,其中包含一些脚本,可以获取访问令牌。

因此,我的问题:通过跳过客户端身份validation步骤获得了什么?

下面是我的想法:在授权代码stream中授权代码+令牌的目的是令牌和客户端秘密永远不会暴露给资源所有者,因为它们在服务器到服务器之间。 另一方面,隐式授权stream程适用于完全使用JavaScript并在资源所有者的浏览器中运行的客户端。 你不需要任何服务器端代码来使用这个stream程。 那么,如果资源所有者的浏览器中发生了一切,那么再发出authentication码和客户端密码就没有意义了,因为令牌和客户端密码仍然会与资源所有者共享。 包括授权代码和客户机密码只是使stream程更加复杂,而不增加任何更真实的安全性。

那么关于“获得了什么?”的答案 是“简单”。

这是出于安全原因,不是为了简单。

您应该考虑用户代理客户端之间的区别:

用户代理是用户(“资源所有者”)与系统的其他部分(authentication服务器和资源服务器)进行通信的软件。

客户端是想要在资源服务器上访问用户资源的软件。

在解耦用户代理和客户端的情况下, 授权代码授权是有意义的。 例如,用户使用Web浏览器(用户代理)通过他在Kickstarter上的Facebook帐户login。 在这种情况下,客户端是Kickstarter的服务器之一,它处理用户login。 该服务器从Facebook获取访问令牌和刷新令牌。 因此,这种types的客户端被认为是“安全的”,由于访问受限,令牌可以被保存,Kickstarter可以访问用户的资源,甚至刷新访问令牌,而无需用户交互。

如果用户代理和客户端耦合(例如本地移动应用程序,JavaScript应用程序),则可以应用隐式授权工作stream程 。 它依赖于资源所有者的存在(用于input凭据)并且不支持刷新令牌。 如果此客户端存储访问令牌供以后使用,这将是一个安全问题,因为该令牌可以容易地被其他应用程序或客户端的用户提取。 刷新标记的缺失是一个额外的提示,即此方法不适用于用户不存在的情况下访问用户资源。

通常的解释是隐式授予在使用JavaScript客户端时更容易实现。 但我认为这是看错的方法。 如果您正在使用通过XMLHttpRequest直接请求受保护资源的JavaScript客户端,隐式授权是您唯一的select,尽pipe它不太安全。

授权代码授权提供了额外的安全性,但只有当您有Web服务器请求受保护的资源时才有效。 由于Web服务器可以存储访问令牌,因此访问令牌暴露给Internet的风险较小,您可以发出持续很长时间的令牌。 由于Web服务器是可信的,因此可以给它一个“刷新令牌”,以便在旧服务器到期时可以获得新的访问令牌。

但是,这是一个很容易忽略的问题 – 只有当Web服务器受到以用户身份validation(login)build立的会话保护时,授权代码stream的安全性才有效。 如果没有会话,不受信任的用户可以使用client_id向Web服务器发出请求,并且与用户具有访问令牌的情况相同。 添加会话意味着只有经过身份validation的用户才能访问受保护的资源。 client_id只是JS webapp的“身份”,而不是所述webapp的authentication。

这也意味着您可以在OAuth令牌过期之前结束会话。 没有标准的方法来使访问令牌失效。 但是,如果您的会话过期,访问令牌是没有用的,因为没有人知道它,但Web服务器。 如果不受信任的用户访问了会话密钥,只要会话有效,他们就只能访问受保护的资源。

如果没有Web服务器,则必须使用隐式授权。 但是这意味着访问令牌暴露于互联网。 如果不可信用户可以访问它,他们可以使用它,直到它到期。 这意味着他们将有权访问它的时间超过授权代码授权。 因此,您可能需要考虑使令牌尽快过期,并避免提供对更多敏感资源的访问。

它归结为:如果用户正在运行基于浏览器的或“公共”(JavaScript)Web应用程序,而没有服务器端组件,则用户隐式地信任应用程序(以及它运行的浏览器,可能与其他浏览器基于应用程序…)。

没有第三方远程服务器,只有资源服务器。 授权代码没有任何好处,因为除了浏览器代表用户操作外,没有其他代理。 出于同样的原因,客户端凭据没有任何好处。 ( 任何客户都可以尝试使用此stream程。)

然而,安全影响是显着的。 从http://tools.ietf.org/html/rfc6749#section-10.3

当使用隐式授权types时,访问令牌在URI片段中被传送,这可以将其暴露给未授权方。

http://tools.ietf.org/html/rfc6749#section-10.16

资源所有者可以通过向攻击者的恶意客户端授予访问令牌而乐意将访问权限委托给资源。 这可能是由于networking钓鱼或其他借口

我不确定我是否正确理解答案和丹的评论。 在我看来,答案已经说明了一些事实是正确的,但它确实指出了OP所要求的。 如果我理解正确,隐式授权stream程的主要优点是像JS应用程序(例如Chrome扩展)的客户端不必公开客户端的秘密。

丹·塔夫林说:

…在授权代码stream中,资源所有者永远不需要查看访问令牌,而在JavaScript客户端中是不可避免的。 客户端的秘密仍然可以保持从JavaScript客户端使用授权码stream,但..

也许我误解了你,但客户端(在这种情况下,JS应用程序)必须将客户端凭证(客户端密钥和秘密)传递到授权代码stream中的资源服务器,对不对? 客户端的秘密不能被“保存JS”。

除了其他答案之外,还需要认识到,隐式configuration文件只允许前置信道stream,而不是需要回拨授权服务器的授权码stream。 这在OpenID Connect中变得很明显,OpenID Connect是构build在Auth 2.0之上的SSO协议,Implicitstream类似于非常受欢迎的SAML POST绑定,Authorization Codestream类似于广泛部署的SAML Artifact绑定

我的问题是: http : //tools.ietf.org/html/rfc6749#section-10.3

它说访问令牌应该在运输和存储过程中保密。 现在在隐式stream的情况下:

  1. 传输层可以使用TLS(HTTPS)
  2. 关于存储。 如何在客户端应用程序中存储访问令牌(比如6到12个小时到期)?

在隐式stream程中,如果用户的浏览器被破坏(邪恶的扩展/病毒),那么腐败就会获得用户的资源,并可以做坏的事情。

在身份validationstream程中,腐败不能因为不知道客户端密码。

我想威尔·凯恩(Will Cain)回答说:“出于同样的原因,客户端证书没有任何好处(任何客户端都可以尝试使用这个stream程)。”还要考虑到隐式stream程的redirect_uri可能是“localhost” – 没有callback是由授权服务器为隐式stream而创build的。 由于没有办法预先信任客户端,所以用户将不得不批准发布用户声明。

https://tools.ietf.org/html/rfc6749#page-8

含蓄

隐式授权是针对在浏览器中使用诸如JavaScript之类的脚本语言实现的客户端而优化的简化的授权码stream。 在隐式stream程中,不是向客户端颁发授权码,而是直接(由于资源所有者授权)发布访问令牌。 授权types是隐含的,因为没有中间凭证(例如授权代码)被发出(并且稍后用于获得访问令牌)。

在隐式授权stream程中发出访问令牌时,
授权服务器不authentication客户端。 在一些
情况下,客户端身份可以通过redirectURI进行validation
用于将访问令牌传递给客户端。 访问令牌可能会暴露给资源所有者或其他访问资源所有者的用户代理的应用程序。

隐性赠款可以提高一些人的反应速度和效率
客户端(例如作为浏览器内应用程序实现的客户端),
因为它减less了获得一个所需的往返次数
访问令牌。