我有以下架构。
哪里:
我正在使用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令牌将作为承载授权传递给资源服务器。相同的令牌在到期之前可以多次重复使用。
作为Authorize请求的一部分,我传递state和nonce值。
目前,我使用简单的if
在JavaScript中验证客户端的状态:
function isValid() {
if (token.state !== expectedState) {
return false;
}
...
}
如果我理解正确,nonce是为了防止重放攻击 - 我认为这是针对我的资源服务器,但也许是针对client。
我不确定在哪里(或者如果)我应该验证nonce。
在服务器上看似不对,整个令牌正在被验证,并且令牌意味着可重用(在其到期内)。
在客户端,似乎是一个更好的位置,但是验证状态有什么不同吗?
我不确定在哪里(或者如果)我应该验证nonce。
当然,您应该验证nonce。因为nonce
是必需的,它将被退回并包含在id_token
的索赔中。验证id_token
时,您只需验证nonce声明。使用nonce是为了缓解令牌重放攻击(想要使用令牌重放攻击的人不会知道nonce,因此每个令牌都有不同的nonce来标识请求的来源)。
对于AAD v2端点的nonce有一个明确的解释:
nonce
(required)由应用生成的请求中包含的值,该值将包含在生成的
id_token
中作为声明。然后,应用程序可以验证此值以减轻令牌重放攻击。该值通常是随机的唯一字符串,可用于标识请求的来源。
因此,您只需验证id_token即可验证nonce。
但验证国家有什么不同吗?
是的,nonce的效果与州不同。首先,nonce将在id_token
中返回,您可以在解码和验证id_token
时对其进行验证。但state
在回复中返回,而不是在令牌中。此外,state
与nonce有不同的含义和效果。
state
(recommended)请求中包含的值,也将在令牌响应中返回。它可以是您希望的任何内容的字符串。随机生成的唯一值通常用于防止cross-site request forgery attacks。状态还用于在发生身份验证请求之前编码有关用户在应用程序中的状态的信息,例如他们所在的页面或视图。
另外,重放攻击不同于跨站点请求伪造攻击。您可以参考有关这两种攻击的更多详细信息。然后,您将理解为什么nonce
在令牌中并且state
在响应中。
是否在客户端验证nonce(令牌)
通常,您可以选择在客户端代码中验证id_token
,但通常的做法是将id_token
发送到后端服务器并在那里执行验证。
根据架构,它应该意味着在客户端和资源服务器上验证令牌。对于SPA,我们可以使用ADAL.js验证nonce
,id_token
包含nonce
声称可以缓解令牌重放攻击。
希望这可以帮助!
总的来说,我建议使用优秀的oidc-client认证库为您完成此操作
Azure AD很棘手,但我有一个记录的样本,我们在上一家公司使用过:http://authguidance.com/2017/11/30/azure-active-directory-setup/
如果它有帮助,很高兴回答任何问题..