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