我有一个 ASSP.NET MVC Web 应用程序
MyWebApp
,它不允许匿名访问任何页面。配置了 IdentityServer4
,一旦用户尝试打开 MyWebApp
,他就会被重定向到 IdentityServer 登录页面。 (混合流)
用户没有登录并在 IdentityServer 登录页面停留足够长的时间,因此 Nonce
上的 MyWebApp
cookie 会过期(默认生存期为 15 分钟)。
如果他继续登录 IdentityServer(成功)并被重定向回 MyWebApp
,他会收到以下错误:
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolInvalidNonceException IDX21323:RequireNonce 为“[PII 已隐藏]”。 OpenIdConnectProtocolValidationContext.Nonce 为空, OpenIdConnectProtocol.ValidatedIdToken.Payload.Nonce 不为空。这 无法验证随机数。如果不需要检查nonce,则设置 OpenIdConnectProtocolValidator.RequireNonce 为“false”。请注意,如果 找到“nonce”将对其进行评估。
但是由于用户已在 IdentityServer 中成功进行身份验证,因此当他再次尝试访问
MyWebApp
时,他会被重定向到 IdentityServer
然后返回到 MyWebApp
,而无需再次输入用户名/密码。然而最初的错误很烦人。当“登录”流程开始并且用户“AFK”时间足够长,以至于“Nonce”cookie 过期并且他无法完成最终验证时,有人遇到过这样的问题吗?处理这种情况的好方法是什么?
提前致谢!
错误
IDX21323: RequireNonce is '[PII is hidden]'
告诉您,您从 MyWebApp
向 IdentityServer
发出请求时所在的 URL 与 IdentityServer
在身份验证后将您重定向到的 URL 不同。
我通过让
MyWebApp
侦听多个 URL 遇到此错误。例如,用户将连接到 www.MyWebApp.com
。他会点击 Login
并被重定向到 IdentityProvider
。他会登录 IdentityProvider
,然后向他发送一个 cookie,证明他的 www.MyWebApp.com
身份。但是,IdentityProvider would then redirect him to my authentication endpoint (which I specified in my app) at
MyWebApp.com. The change in the URL meant that his cookie was inaccessible to
MyWebApp.com`,应用程序会抛出错误。
当我刷新页面时,我已经在
MyWebApp.com
了。现在,当他点击Login
时,他将被重定向到IdentityProvider
。因为他已经登录了,所以会生成一个 cookie 并提供给MyWebApp.com
(这与用户上次连接www.MyWebApp.com
时不同)。当 IdentityProvider
POST 到我的身份验证端点时,应用程序可以访问 cookie,并且用户已成功登录。
TL;博士。用户连接的 URL 必须与身份验证成功后您的
IdentityProvider
重定向到的 URL 完全匹配。根据您的应用程序的配置方式,将应用不同的 cookie 规则。就我而言,加密(http 与 https)或子域(www 与无 www)的差异导致用户似乎随机拥有 IDX21323 error PII is hidden
我只是更新了 Microsoft.Owin.Security.OpenIdConnect 包以匹配其他 OWin 包上的版本号。
Microsoft.Owin [4.1.1]
Microsoft.Owin.Security [4.1.1]
Microsoft.Owin.Security.Cookies [4.1.1]
,错误就消失了。
在我的例子中,异常 IDX21323 与开发环境中使用 http 协议有关。
OpenIdConnectAuthenticationHandler
中的
当前实现(重定向到授权服务器时)为具有硬编码
SameSite=None
属性的用户代理设置一个nonce cookie。如果代理不通过 https 协议进行通信,则不会为 cookie 指定
Secure
属性:
new CookieOptions
{
SameSite = SameSiteMode.None,
HttpOnly = true,
Secure = Request.IsSecure,
Expires = DateTime.UtcNow + Options.ProtocolValidator.NonceLifetime
}
此实现的结果是用户代理拒绝nonce cookie(根据规范,如果
SameSate
是None
,则需要Secure
属性)。
因此在生产环境中需要使用https。然而,在开发环境中,可以使用 Firefox 浏览器作为用户代理,在标准配置中不需要
SameSite=None
的安全上下文。
在 OpenIdConnectAuthenticationNotifications 中,您可以捕获错误并继续执行下一个中间件:
AuthenticationFailed = (context) =>
{
if (context.Exception.Message.Contains("IDX21323"))
{
context.SkipToNextMiddleware();
return Task.FromResult(0);
}
return Task.FromResult(0);
如果我记得的话,IDS3 需要随机数,但 IDS4 不需要