OAuth 2.0"状态"和OpenID"nonce"参数之间的区别?为什么国家不能重复使用?

dvs*_*gec 43 oauth oauth-2.0 openid-connect

OAuth 2.0定义了客户端请求发送的"状态"参数,以防止跨站点请求攻击.在OpenID规范中提到"nonce"也是如此.除了在ID令牌而不是查询参数中返回"nonce"这一事实之外,它们看起来服务于完全相同的目的.如果有人能解释他们为何分开

Kav*_*uwa 49

状态和随机数似乎相似.但如果你深入挖掘,你会发现它们有不同的用途.

State可以保护最终用户免受跨站点请求伪造(CSRF)攻击.它是从OAuth 2.0协议RFC6749中引入的.议定书指出,

一旦从最终用户获得授权,授权服务器就会使用"state" 参数中包含的所需绑定值将最终用户的用户代理重定向回客户端.绑定值使客户端能够通过将绑定值与用户代理的已验证状态进行匹配来验证请求的有效性

这用于授权请求.它使客户端能够验证授权响应是否未被原始服务器更改并由auth发送.请求已发送.简而言之,它允许客户端交叉检查授权请求和响应.

Nonce有不同的用途.它将令牌与客户绑定在一起.它用作令牌验证参数,并从OpenID Connect规范中引入.

nonce - 用于将客户端会话与ID令牌相关联并减轻重放攻击的字符串值.该值通过未经修改从身份验证请求传递到ID令牌.如果存在于ID令牌中,客户端必须验证nonce Claim Value是否等于Authentication Request中发送的nonce参数的值.如果存在于认证请求中,则授权服务器必须在ID令牌中包含一个nonce Claim,其中Claim Value是在Authentication Request中发送的nonce值.授权服务器不应该对使用的nonce值执行任何其他处理.nonce值是区分大小写的字符串

如您所见,nonce值来自授权请求,它由客户端生成.如果包含nonce,它将出现在令牌中.因此,客户端可以根据初始授权请求验证它收到的令牌,从而确保令牌的有效性.

此外,根据流类型,nonce可以是必需参数.隐式流和混合流要求nonce值.这两个值都由客户端应用程序生成验证.

为什么国家不能重复使用?

如果捕获了授权请求,则恶意方可以伪造授权响应.这可以通过改变状态参数来避免.

  • @avisiboni 要接受授权代码响应,客户端需要接受来自授权服务器的响应(例如:- 在网页中,这可以通过重定向和表单发布到后端来完成)。这意味着,我们的客户端应用程序有一个打开并接受请求的端点。状态参数通过将原始授权请求绑定到响应来保护此端点。这就是CSRF保护。Nonce 完全不同,并且两者都有不同的用途。 (3认同)
  • 如果我们将 ID 令牌中的状态本身作为 nonce 传递给它,那么会有什么不利之处。使用外层防止CSRF,使用内层在客户端绑定会话。 (2认同)
  • 很抱歉,迟到了,但是对于可以从响应中取出状态参数的说法完全杀死了状态参数的目的。另外,如果两个参数都使用相同的参数,则在使用OpenID Connect流时,复杂的攻击将不起作用,因为从反向通道调用收集的ID令牌将具有相同的参数,并且客户端可以比较两个调用的state参数以检查是否有效较早拨打的电话。 (2认同)

Pit*_*kos 9

Nonce 向浏览器回答了这个问题:这个 ID 令牌是对我的初始请求的响应吗?

对后端服务器的状态回答:同意真的来自我认为的人吗?

所以他们回答类似的问题,但针对不同的实体。

  • 这不是相反吗?据我了解,“state”用于浏览器,“nonce”用于服务器。 (6认同)

小智 8

实际上“NONCE”足以验证发送者和响应。但在此之前你应该打开令牌读取“NONCE”。因此,如果有数百万个虚假回复,您必须接受回复,您将接受所有这些来打开令牌并读取“NONCE”。但是状态已在响应标头上打开,您可以轻松读取状态并轻松拒绝虚假响应。这是两级检查。


Nic*_*Dao 7

除了上面关注 和 安全方面的答案之外statenonce如果您正在实现自己的三足 OAuth2 工作流程(客户端、中间件和联合身份提供商,例如 Facebook),您的中间件有时可能需要一些上下文。例如,当来自 FIP 的响应在返回到客户端之前返回到中间件时,您可能需要了解有关原始请求(即对 FIP 的原始请求)的详细信息。因为您的中间件很可能是无状态的,所以在没有任何帮助的情况下它无法回答这个问题。这就是 OAuth2state变量的用武之地。您可以存储表示您想要在所有 OAuth2 跳转之间传递的状态的任何字符串,以便您的中间件(以及您的客户端)可以使用更多上下文。对于您的客户端,这是出于安全原因而使用的。出于纯粹的安全原因,将其nonce用作 OIDC 规范的一部分。


May*_*ghe 6

我正在从他们的 RFC 中说明一个解释。解释很简单。

状态

客户端用于维护请求和回调之间的状态的不透明值。授权服务器在将用户代理重定向回客户端时包含此值。该参数应该用于防止跨站点请求伪造

随机数

nonce 参数值需要包含每个会话的状态,并且攻击者无法猜测。为 Web 服务器客户端实现此目的的一种方法是将加密随机值存储为 HttpOnly 会话 cookie,并使用该值的加密哈希作为 nonce 参数。在这种情况下,将返回的 ID 令牌中的随机数与会话 cookie 的哈希值进行比较,以检测第三方对 ID 令牌的重放。一种适用于 JavaScript 客户端的相关方法是将加密随机值存储在 HTML5 本地存储中,并使用该值的加密哈希。

参考链接:状态:https : //datatracker.ietf.org/doc/html/rfc6749

随机数:https : //openid.net/specs/openid-connect-core-1_0-17_orig.html

希望这能回答你的问题。

  • “不言自明”是一个非常主观的事情。我已经阅读了规格,但仍然没有明白其中的区别。不要假设你的理解水平与一个正在提出有关微妙问题的人的理解水平相同。 (8认同)
  • 只是 -1,因为我认为 OP 更多的是要求解释两者的使用方式的差异,而不是 RFC 的片段。 (5认同)
  • 正如我在回答中提到的,RFC 中的片段是不言自明的。 (4认同)