Oauth 2.0 在OAuth 2.0隐式流中在何处验证nonce?

Oauth 2.0 在OAuth 2.0隐式流中在何处验证nonce?,oauth-2.0,jwt,azure-active-directory,single-page-application,openid-connect,Oauth 2.0,Jwt,Azure Active Directory,Single Page Application,Openid Connect,我有以下架构 其中: 客户端-是一个单页JavaScript应用程序 授权服务器-是Azure AD 资源服务器-是使用的Azure应用程序服务 所有通信都使用HTTPS进行保护 我正在使用从Azure AD访问JWT访问令牌 https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize? client_id=6731de76-14a6-49ae-97bc-6eba6914391e &response_type=i

我有以下架构

其中:

  • 客户端-是一个单页JavaScript应用程序
  • 授权服务器-是Azure AD
  • 资源服务器-是使用的Azure应用程序服务
  • 所有通信都使用HTTPS进行保护
我正在使用从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令牌随后作为承载授权传递给资源服务器。同一令牌在到期之前可以重复使用多次

作为授权请求的一部分,我传递state和nonce值

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

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

    ...
}
如果我理解正确的话,nonce是为了防止重播攻击——我认为这意味着针对我的资源服务器,但也可能针对服务器

我不确定应该在何处(或是否)验证nonce

在服务器上,令牌作为一个整体正在被验证,并且令牌应该是可重用的(在其有效期内)

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

我不确定应该在何处(或是否)验证nonce

当然,您应该验证nonce。因为
nonce
是必需的,它将作为声明返回并包含在
id\u令牌中。当您验证
id\u令牌时,您只需验证nonce声明。使用nonce是为了减轻令牌重放攻击(想要使用令牌重放攻击的人不知道nonce,因此每个令牌都有不同的nonce来标识请求的来源)

AAD v2端点的nonce有一个明确的解释:

nonce
(必选) 应用程序生成的请求中包含的值,,将 作为索赔包含在生成的
id\u令牌中。然后,应用程序可以验证
此值用于减轻令牌重播攻击。该值通常为
随机的、唯一的字符串,可用于标识
请求

因此,您可以只验证id_令牌来验证nonce

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

是的,临时状态的效果不同于状态。首先,nonce将在
id\u令牌中返回,您可以在解码和验证
id\u令牌时对其进行验证。但是
状态
在响应中返回,而不是在令牌中返回。而且,
state
与nonce具有不同的含义和效果

状态
(推荐) 请求中包含的值,该值也将在 令牌响应。它可以是您想要的任何内容的字符串A 随机生成的唯一值通常用于防止 。状态也用于编码 有关用户在应用程序中的状态的信息 发生身份验证请求,例如它们所访问的页面或视图 开

另外,重播攻击不同于跨站点请求伪造攻击。有关这两次攻击的更多详细信息,请参阅。然后,您将了解为什么
nonce
在令牌中,而
state
在响应中

是否在客户端验证nonce(令牌)

对于
id\u令牌
,是的,应该从客户端验证它。 对于具有隐式流的SPA,我们可以使用来验证
nonce
id\u令牌
,该令牌包含
nonce
声明以减轻令牌重放攻击


希望这有帮助

一般来说,我建议您使用优秀的oidc客户端认证库来完成这项工作

Azure广告很棘手,但我有一个记录在案的样本,我们在上一家公司使用过:


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

在此上下文中,
应用程序可以验证
,该应用程序是客户端JavaScript应用程序吗?是的,这是我困惑的一部分。nonce是在客户机中创建的,并且只有客户机知道,因此从逻辑上讲,nonce必须在客户机中进行验证-现在已经查看了nonce,似乎他们也在通过读取Base64编码的JWT来验证客户机中的nonce。@JamesWood。对,对于SPA,我们使用ADAL.js验证令牌。这里,我们在SPA客户端中验证
id\u令牌
,以减轻令牌重放攻击。