【发布时间】:2020-04-17 01:41:49
【问题描述】:
我试图了解 OAuth2.0 提供的各种授权类型。我一直在阅读它,并且有很多资源可以详细解释它,例如 this、this 和 this 引用一些。
在授权码授予类型的情况下,据我了解有两个步骤。
第 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