OAuth中授权码的用途是啥

Posted

技术标签:

【中文标题】OAuth中授权码的用途是啥【英文标题】:What is the purpose of authorization code in OAuthOAuth中授权码的用途是什么 【发布时间】:2019-05-28 10:59:17 【问题描述】:

在 oauth 中,您使用客户端 ID/秘密发出请求以获取授权码。然后您发出第二个请求以交换访问令牌的授权代码。我的问题是:

为什么需要这两个步骤而不是首先获取访问令牌?它如何使整个过程更加安全?还是有别的原因。

我说的是服务器端应用程序(例如 php)从远程服务器请求授权,而不是 javascript

【问题讨论】:

【参考方案1】:

可以通过单个请求来完成 - 然后称为隐式流。有一个请求将response_type 设置为tokenid_token token

使用访问代码(授权流程)而不是直接返回令牌的一般想法是对最终用户隐藏它们。第二个请求通常由后端服务器而不是浏览器完成。

您可以在此处找到更多详细信息:https://auth0.com/docs/api-auth/which-oauth-flow-to-use

注意:完整答案请阅读 cmets。

【讨论】:

但是访问代码对用户(或用户机器上的软件)没有隐藏。如果像浏览器插件这样的不良软件首先将访问代码交换为令牌怎么办。授权服务器将redirect_url 仅用作登录页面会更安全,而是通过直接发布请求将代码发布到客户端应用程序而根本不通过用户浏览器。 访问代码不是 - 但是要将访问代码交换为令牌,您需要提供用户未知的 client_id 和 client_secret。 那么根本不需要访问码。在服务器授予对您的客户端 ID/秘密的访问权限后,您可以请求访问令牌。服务器知道您有权访问。为什么需要访问码来证明? 客户端 ID 和密码用于应用程序 - 不用于用户。访问代码是根据用户凭据授予的。所以我(Jakub)登录到 LinkedIn 并获取访问代码。然后,您的应用程序使用我的访问代码和您的客户 ID/秘密从 LinkedIn 检索我的访问令牌 不再推荐隐式授权类型。对于公共客户端,您应该始终将授权码授予类型与 PKCE 一起使用【参考方案2】:

在 oauth 中,您使用您的客户端 ID/秘密发出请求以获取授权码。

授权码请求不包含客户端密码。它仅包含客户端 ID 和重定向 url,使授权服务器能够验证请求是否来自已知客户端。

这两个步骤需要什么而不是首先获取访问令牌?它如何使整个过程更加安全?还是有其他原因。

如果我们忘记了隐式流程,它涉及从第一次调用中检索访问令牌,我会说这是为了提高安全性。

当使用授权码流时,您使用用户代理(浏览器)来启动流。这意味着,用户代理会将最终用户重定向到授权服务器进行身份验证(用户名密码获取和验证最终用户)。如果最终用户验证成功,授权服务器将发送授权码。这是一个临时秘钥,与原始授权码请求绑定。

现在客户端使用授权码并直接联系授权服务器以获取访问(和其他)令牌。第二步发生在用户代理之外。

如果客户端是机密客户端,即具有客户端 ID 和客户端密码的客户端,则第二次调用将需要生成此客户端密码。所以它内部包含一个客户端验证过程。从授权服务器的角度来看,如果客户端身份验证失败,令牌请求将被拒绝。这为授权码窃取提供了保护。

此外,通过第二步,我们避免访问令牌暴露给第三方。例如,在隐式流中,访问令牌通过用户代理作为 URL 片段发送。如果用户代理遭到破坏(例如:被某些恶意代码操纵),则可以提取此访问令牌。

公共客户呢?这意味着由于其性质而无法获得客户端机密的客户端(例如:- 无法通过存储来保护机密的客户端)

公共客户端使用PKCE。必须使用它来避免授权码被盗。所以在令牌请求(第二次调用)中,客户端会直接发送验证码。用户代理无法在第一个请求中获取代码验证器,因为它已被散列(代码质询)。所以令牌请求现在包含一个只有客户端和授权服务器知道的秘密。

如果您比较这两种情况(公共和机密客户端),您可以看到第二次调用如何增加了额外的安全层。

【讨论】:

【参考方案3】:

更安全...还是更少?取决于它是如何应用的。

看看: https://auth0.com/docs/api-auth/which-oauth-flow-to-use

您会注意到在服务器端使用身份验证代码流时。另请注意,当请求验证码时,响应 url 有一个带问号的查询字符串:https://example-app.com/redirect?code=g0ZGZmNjVmOWI&state=dkZmYxMzE2

使用水疗中心时,您将使用隐式流程。请注意,accesstoken 是通过 url https://example-app.com/redirect#access_token=MyMzFjNTk2NTk4ZTYyZGI3 中的锚点(#)发送的

锚值永远不会发送到服务器。它仅适用于水疗中心的客户。服务器将永远无法看到访问令牌。

当服务器应用程序获得重定向时,它必须能够读取它。可以,因为 url 有一个问号而不是 #。如果它直接发送令牌,客户端可以在他的浏览器历史记录中看到访问令牌,或者通过提琴手。

【讨论】:

以上是关于OAuth中授权码的用途是啥的主要内容,如果未能解决你的问题,请参考以下文章

为 OAuth2 生成授权码的规范是啥?

OAuth2 中客户端密码的用途是啥?

Javassist。主要思想是啥,真正的用途是啥?

ASP.NET Core 2.0+ 中 JwtBearerOptions.SaveToken 属性的用途是啥?

.net 中 PerformanceCounter 类的用途是啥?

Lambda表达式的主要用途是啥?