在 OAuth 2.0 隐式流中验证​​ nonce 的位置?

Posted

技术标签:

【中文标题】在 OAuth 2.0 隐式流中验证​​ nonce 的位置?【英文标题】:Where to validate nonce in OAuth 2.0 Implict Flow? 【发布时间】:2018-10-04 16:54:54 【问题描述】:

我有以下架构。

地点:

客户端 - 是一个单页 javascript 应用程序。 授权服务器 - 是 Azure AD。 资源服务器 - 是使用 Azure AD authentication 的 Azure 应用服务。 所有通信均使用 HTTPS 保护。

我正在使用 Implicit Flow 从 Azure AD 访问 JWT 访问令牌。

https://login.microsoftonline.com/tenant/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=id_token+token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=openid%20https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&response_mode=fragment
&state=12345
&nonce=678910

此 JWT 令牌随后会作为承载授权传递给资源服务器。同一个令牌可以在过期前多次重复使用。

作为授权请求的一部分,我传递状态和随机数值。

目前我使用简单的if 在 JavaScript 中验证客户端上的状态:

function isValid() 
    if (token.state !== expectedState) 
        return false;
    

    ...

如果我理解正确,nonce 是为了防止重放攻击 - 我认为这意味着针对我的资源服务器,但也可能针对 client。

我不确定我应该在哪里(或是否)验证随机数。

在服务器上似乎不对,令牌作为一个整体正在被验证,并且令牌是可重复使用的(在其到期内)。

在客户端,似乎是一个更好的位置,但这与验证状态有什么不同吗?

【问题讨论】:

【参考方案1】:

我不确定我应该在哪里(或是否)验证随机数。

当然,您应该验证随机数。因为nonce 是必需的,它将作为声明返回并包含在id_token 中。当您验证 id_token 时,您只需验证 nonce 声明。使用nonce是为了缓解token replay攻击(想要使用token replay攻击的人不会知道nonce,所以每个token都有不同的nonce来识别请求的来源)。

对于 AAD v2 端点的 nonce 有明确的解释:

#nonce(必填)

请求中包含的值,由应用生成,将是 包含在生成的id_token 中作为声明。然后应用程序可以验证 此值以减轻令牌重放攻击。 该值通常是 随机的、唯一的字符串,可用于识别 请求。

因此,您只需验证 id_token 即可验证 nonce。

但这与验证状态有什么不同吗?

是的,nonce 的效果与 state 不同。首先,nonce 将在id_token 中返回,您可以在解码和验证id_token 时对其进行验证。但是state 在响应中返回,而不是在令牌中。另外,state 与 nonce 有不同的含义和效果。

#state(推荐)

请求中包含的值也将在 令牌响应。它可以是您想要的任何内容的字符串。 一个 随机生成的唯一值通常用于防止 cross-site request forgery attacks。状态也用于编码 用户在应用程序中的状态信息 发生了身份验证请求,例如它们所在的页面或视图 开。

另外,重放攻击不同于跨站请求伪造攻击。您可以参考有关这两种攻击的更多详细信息。然后,您就会明白为什么nonce 在令牌中而state 在响应中。

是否在客户端验证随机数(令牌)

对于id_token,是的,它只是应该从客户端验证。 对于带有隐式流的 SPA,我们可以使用 ADAL.js 来验证 nonce,其中包含 nonce 声明的 id_token 可以缓解令牌重放攻击。

希望这会有所帮助!

【讨论】:

在这种情况下The app can then verify,应用程序是客户端 JavaScript 应用程序吗? 是的,这是我困惑的一部分。随机数是在客户端中创建的,并且只有客户端知道,所以从逻辑上讲,必须在客户端中验证随机数 - 现在查看了ADAL.js,看起来他们也在通过简单地验证客户端中的随机数读取 Base64 编码的 JWT。 @JamesWood。对,对于 SPA,我们使用 ADAL.js 验证令牌。这里我们验证 SPA 客户端中的 id_token 以缓解令牌重放攻击。【参考方案2】:

一般来说,我建议您使用优秀的 oidc-client 认证库来为您执行此操作

Azure AD 很棘手,但我有一个有效的文档示例,我们在上一家公司使用过该示例: http://authguidance.com/2017/11/30/azure-active-directory-setup/

如果有帮助,很乐意回答任何问题..

【讨论】:

以上是关于在 OAuth 2.0 隐式流中验证​​ nonce 的位置?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以仅请求用户已在 Azure AD OAuth2 隐式流中同意的范围的子集?

OAuth2 隐式流程 - IFrame 刷新身份

自定义声明包含在隐式流中,但不包含在 PKCE 流中

Azure api OAuth2 隐式流适用于 http 但不适用于 htt

logoutid 在身份 server4 的隐式流中不可用

如何在 SPA 中实现 OAuth 隐式流?