【问题标题】:Oauth2.0 Authorization Code Grant ClientId & Secret ConfusionOauth 2.0 授权码授予 ClientId 和 Secret 混淆
【发布时间】:2020-04-17 01:41:49
【问题描述】:

我试图了解 OAuth2.0 提供的各种授权类型。我一直在阅读它,并且有很多资源可以详细解释它,例如 thisthisthis 引用一些。

在授权码授予类型的情况下,据我了解有两个步骤。

第 1 步 - 获取授权码本身

假设用户在浏览器中打开了应用程序,例如AwesomeApp。这个应用程序有一个选项,比如说 用 Facebook 登录,用户选择继续。这将使用查询参数中所需的详细信息向授权服务器(在我们的示例中为 Facebook)发起 GET 请求,例如(取自上面链接的资源之一):

https://authorization-server-of-facebook.com/auth?response_type=code&
  client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=photos&state=1234zyx

现在我理解了每个参数的含义(再次感谢资源)。我还了解到,在AwesomeApp 可以拨打此电话之前,它必须已在 Facebook 注册以接收客户端 ID 和客户端密码(通过某种方式)。

现在,一旦用户批准请求,facebook 的授权服务器就会通过将用户的浏览器重定向回(在上述请求中)提供的重定向 uri 并使用授权代码来响应上述请求。

第 2 步 - 将授权码换成实际的访问令牌

现在AwesomeApp 需要将上面收到的授权码换成访问令牌。为此,AwesomeApp 发出如下所示的 POST 请求:

POST https://api.authorization-server-of-facebook.com/token
  grant_type=authorization_code&
  code=AUTH_CODE_RECEIVED_IN_THE_ABOVE_STEP&
  redirect_uri=REDIRECT_URI&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET

对于上述请求,facebook 的授权服务器返回访问令牌、刷新令牌、到期时间等。

现在我的问题在上面的第 2 步。这个 POST 不应该是后端调用吗?为什么?因为它也需要在请求中发送客户端密码。如果从AwesomeApp 的前端进行,很容易泄露给虚假用户。不是吗?

所以我在想,应该是这样的,从上述请求的响应中检索访问令牌(和其他详细信息),然后将其传递给它的前端。这不是应该的样子吗?

现在在我遇到的大多数资源(包括上述链接)中,它讨论了PKCE Extension,它讨论了每次生成动态客户端密码。但是,如果 POST(步骤 2 中的那个)仍然是从前端本身完成的,那会更好吗?此外,如果每次都动态生成此客户端机密,那么它也可能由虚假用户完成,不是吗。我的意思是授权服务器如何验证发出请求的客户端确实是它允许的客户端? (在客户端密码的情况下,这是有道理的,因为客户端密码是由 Facebook 的授权服务器提供给 AwesomeApp 的。在这种情况下它不会,因为这个密码是由客户端自己生成的)。

以上所有的误解是什么?

按照here 解释的流程,code_verifier 如何防止对手作为正版应用进行游戏?与客户端密码不同,攻击者永远无法冒充真正的客户端(当然,除非客户端密码本身被某种方式泄露),在这种情况下,攻击者可以简单地发送任何code_verifier。在code_verifier 的令牌请求和验证以及最终响应出现之前,授权服务器如何验证授权请求确实来自真正的客户端?

【问题讨论】:

    标签: oauth oauth-2.0 authorization


    【解决方案1】:

    您正确理解了授权码流程。在最初的 OAuth2 规范中,代码流适用于 confidential clients(即在服务器上运行的传统 Web 应用程序)。隐式流旨在用于在浏览器内运行的应用程序,例如单页应用程序。隐式流通过重定向 URI 直接将访问令牌传递给客户端。

    现在隐式流容易受到令牌泄漏(引荐标头和服务器日志)的影响,因此发明了PKCE 也将代码流用于公共客户端。它从名为verifier 的标识符生成一个散列值,并将其与授权请求一起发送。当客户端获取代码时,它使用验证者作为秘密向授权服务器证明是客户端发出了原始授权请求(用户登录)。

    即使恶意客户端可以生成授权请求,用户也需要登录并同意客户端获取访问令牌才能访问其数据。如果用户决定信任恶意客户端,则协议无能为力,因为客户端不必对自己进行身份验证。

    【讨论】:

    • rfc6749,声明The authorization code provides a few important security benefits, such as the ability to authenticate the client, as well as the transmission of the access token directly to the client without passing it through the resource owner's user-agent and potentially exposing it to others, including the resource owner. => 意味着当涉及后端并且按照我们在上面的问题中讨论的方式完成时,授权代码流是最好的。在下一条评论中继续...
    • 接上一条评论...虽然 PKCE 仅在隐式流和 SPA(没有后端)的情况下才有意义。但在 PKCE 中,verifier 的哈希值由客户端生成并发送到授权服务器。那你这个When the client gets the code, it uses the verifier as the secret to prove to the authorization server it was the client that made the original authorization request (to which the user signed in).是什么意思?
    • PKCE 并不意味着与隐式流一起使用。代码流 + PKCE 旨在替换隐式流。问题是恶意客户端可以从授权服务器获取令牌,如果他们拦截授权代码并在合法客户端之前使用它。 PKCE 通过要求客户端在发送授权请求时生成的验证程序来防止这种情况。即使恶意客户端得到了挑战,它也无法从中获得验证者。
    • 抱歉,我还是一头雾水。要生成授权代码,必须发出第一个授权请求(在其响应中授权代码被发送回客户端)。 code_challenge 与此请求一起发送。现在,恶意应用程序可以做同样的事情,因为除非此请求到达授权服务器,否则授权服务器不知道code_challenge。对?因此,challenge_code 的整个验证现在将基于恶意应用程序的challenge_code 完成。不是吗?我还缺少什么吗?
    • 对,但是在第一次授权请求和发送授权码之间,资源所有者(用户)必须登录并同意应用程序被授予访问其在资源服务器上的数据的权限。是的,如果恶意客户端应用程序可以欺骗用户登录并给予同意,它就会获得访问权限。 PKCE 的发明是为了防止恶意客户端在未经用户登录和同意的情况下窃取代码并获取令牌。
    猜你喜欢
    • 2020-09-08
    • 1970-01-01
    • 2017-01-10
    • 2012-05-31
    • 2019-07-07
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多