Oauth2.0授权码授予ClientId和秘密混淆

时间:2020-04-17 01:41:49

标签: oauth oauth-2.0 authorization

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

就授权码授予类型而言,据我了解有2个步骤。

步骤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的前端进行操作,则很容易泄漏给虚假的用户。不是吗?

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

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

上述所有误解是什么?

根据hereenter image description here所述的流程,code_verifier如何阻止对手扮演真正的应用程序?与客户端机密不同,在这种情况下,攻击者将永远无法冒充真正的客户端(除非客户端机密本身受到某种程度的损害),在这种情况下,攻击者可以简单地发送任何code_verifier。甚至在令牌请求和code_verifier的验证以及最终响应尚未出现之前,授权服务器将如何验证授权请求确实来自真正的客户端?

1 个答案:

答案 0 :(得分:1)

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

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

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