OWIN OpenIdConnect 中间件 IDX10311 随机数无法验证
Posted
技术标签:
【中文标题】OWIN OpenIdConnect 中间件 IDX10311 随机数无法验证【英文标题】:OWIN OpenIdConnect Middleware IDX10311 nonce cannot be validated 【发布时间】:2017-01-17 15:55:15 【问题描述】:我有一个使用 OpenIdConnect 的 OWIN 中间件的应用程序。 startup.cs 文件使用 app.UseOpenIdConnectAuthentication 的标准实现。 cookie 设置为浏览器,但错误:
IDX10311:RequireNonce 为“真”(默认),但 validationContext.Nonce 为空。无法验证随机数。如果不需要检查 nonce,请将 OpenIdConnectProtocolValidator.RequireNonce 设置为 'false'。
我发现,当像大多数调试项目一样运行 fiddler 时,会发生这种行为。返回错误,但如果我返回该站点,一切正常并且我的用户已通过身份验证。有没有人在运行 fiddler 时看到过这种行为?
使用提琴手:
OpenIdConnect 中的SecurityTokenValidated 通知执行了两次。 第二次通过后抛出 IDX10311 错误 浏览器包含有效的cookie,返回页面我可以查看有效的User.Identity数据。在没有 fiddler 的情况下运行:
SecurityTokenValidated 在 OpenIdConnect 中执行一次 未抛出错误,继续加载控制器操作以进行身份验证后重定向 Uri Cookie 也有效且 User.Identity 数据正确。想法?我可以在不运行 fiddler 的情况下绕过它,但是在调试时最好也运行 fiddler 来检查流量。
【问题讨论】:
可能是这个? github.com/IdentityServer/IdentityServer3/issues/542 谢谢布洛克。我过去看过那个线程。对许多人来说,这似乎是一个未解决的问题。不过,我会从帖子中查看您的建议。我希望这不是 MS Katana 错误,尽管正如 Dominick 所建议的那样,因为 MS 已经有一段时间没有更新该 nuget 包了。 @gilm0079 你找到解决办法了吗? 【参考方案1】:也许是这个原因?
你好,我想我找到了这个问题的根本原因。
我正在总结我的发现:
问题出在 OpenIdConnect.nonce.OpenIdConnect cookie 中
只要 OpenID 中间件启动身份验证会话,就会从应用程序(我们称之为“ID 客户端”)设置此 cookie
身份验证完成后,cookie 应立即从浏览器发送回“ID 客户端”。我的假设是,从 ID 客户端的角度来看,需要对这个 cookie 进行仔细检查(即我是否真的启动了 OpenID Connect 授权流程?)
我的很多困惑是由“Nonce”术语引起的,该术语在此 cookie 和来自 ID 服务器的 OpenID Connect 流中都使用过。
在我的例子中,异常是由缺少 cookie(不是 ID 服务器的 nonce)引起的,仅仅是因为浏览器没有将它发送回“ID 客户端”
所以在我的例子中,主要根是这样的:OpenIdConnect.nonce.OpenIdConnect cookie 没有被浏览器发送回 ID 客户端。在某些情况下(即 Chrome、Firefox 和 Edge)cookie 被正确发送,而在其他情况下(IE11、Safari)则不是。
经过大量研究,我发现问题出在浏览器上定义的 Cookie 限制策略上。就我而言,“ID 客户端”嵌入在 <iframe>
中。这会导致“ID 客户端”被视为“第三方客户端”,因为用户没有直接在主窗口中导航到该 URL。因为这是第三方,所以对于某些浏览器,它的 cookie 必须被阻止。
实际上,通过设置“阻止第三方 cookie”,在 Chrome 上也可以获得相同的效果。
所以,我不得不得出结论:
a) 如果 iframe 是必须的(在我的情况下,因为“ID 客户端”是必须在我们的主平台应用程序的图形内容中运行的应用程序),我认为唯一的解决方案是拦截错误,并且用一个页面处理它,要求用户启用第三方 cookie。
b) 如果 iframe 不是必须的,在新窗口中打开“ID 客户端”就足够了。
希望这对某人有所帮助,因为我疯了!
马可
【讨论】:
删除我的评论。我在考虑一个不同的 ID 服务器问题。虽然,您的回答似乎与我所看到的不同。我的问题只是在调试项目时运行 fiddler 进行流量检查时发生。否则效果很好。 对我来说似乎是浏览器问题。 IE11 确实重现了这个问题,而 FF - 没有。感谢您的建议【参考方案2】:我知道这是一篇旧帖子,但我遇到了这个问题,没有什么对我有用,在我失去了让我的企业应用程序正常工作的解决方案之后,我最终通过在 azure 中将多租户选项设置为是来修复它(在 Azure 中选择:应用注册>设置>属性,将多租户设置为是并点击保存)。
希望它对某人有所帮助,看不到没有人提及它。
【讨论】:
【参考方案3】:我遇到了同样的问题,但将Microsoft.Owin.Security.OpenIdConnect
切换回版本 3.0.1 解决了问题
【讨论】:
对于本地/测试环境版本 >3.0.1 不起作用,我认为与假 SSL 证书有关。但是对于真正的 SSL 证书,版本> 3.0.1 似乎可以正常工作。【参考方案4】:当我切换到在完整 IIS 中托管时,在后台运行 IIS Express 时,我注意到了这个错误。当我禁用 IIS Express 后,我的错误就消失了。
【讨论】:
【参考方案5】:对我来说,在 Azure 活动目录中更改回复 url 是可行的。
当您启用 SSL 时会发生这种情况,因为它仅将登录 URL 更改为 HTTPS URL,而回复 URL 保持相同的 HTTP URL。
当您尝试使用 https URL 访问您的应用程序时,它会在您的浏览器中设置一个具有唯一编号 (nonce) 的 cookie,并点击 Azure AD 进行身份验证。身份验证后,浏览器必须授予对该 cookie 的访问权限。但由于登录 URL 和回复 URL 不同,浏览器无法识别您的应用,也无法访问该 cookie,因此应用会抛出此错误。
【讨论】:
我们遇到了同样的问题。问题本身与 Azure 无关,而是与 OpenIdConnect middeware 如何处理 http 和 https 重定向 url 相关。 但是如何在不禁用 SSL 的情况下解决这个问题? @Heinzlmaen 您不需要禁用 SSL。您需要相应地更改 Azure AAD 中的回复 URL。【参考方案6】:web.config 中的 cookie 重写规则以确保相同站点的 cookie 给出了这个神秘的异常。禁用该规则解决了它。
【讨论】:
你能详细说明这意味着什么吗?【参考方案7】:对通过 Azure Active Directory 保护的应用程序有用的临时解决方案是注销(通过转到站点/帐户/注销页面),然后我能够返回主页并正常登录。希望这对某人有所帮助。
【讨论】:
【参考方案8】:我知道这个已经有一段时间了。我的具体问题是与在 Fiddler(流量检查器代理)运行时使用 IdentityServer 进行身份验证相关的 IDX10311 错误。在主机名包含“localhost”的情况下,我添加了一个自定义 owin 中间件来捕获和吸收 IDX13011。忽略此异常允许我们使用带有 fiddler 的站点作为解决方法。我认为这会导致身份验证过程中断,尽管我们必须在回调的浏览器地址栏中按 enter 才能使其再次运行,但这只会影响开发。
这是我们在中间件中用来吸收错误的调用方法。我应该注意到,我们偶尔也会在生产中看到这个错误。没有解释原因,但我感觉它与使用 IE 浏览器的用户有关。
public override async Task Invoke(IOwinContext context)
try
await Next.Invoke(context);
catch (Exception ex)
_errorHandling = new ErrorHandling();
if (ex.Message.Contains("IDX10803"))
//do something here to alert your IT staff to a possible IdSvr outage
context.Response.Redirect("/Error/IdSvrDown?message=" + ex.Message);
else if(ex.Message.Contains("IDX10311") && context.Request.Host.Value.Contains("localhost"))
//absorb exception and allow middleware to continue
else
context.Response.Redirect("/Error/OwinMiddlewareError?exMsg=" + ex.Message + "&owinContextName=" + lastMiddlewareTypeName);
【讨论】:
【参考方案9】:对我来说,这是一个不同的问题。我的网站正在使用以下两个网址
https://www.example.com 和 https://example.com
但我的重定向网址是https://www.example.com。
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
ClientId = ConfigurationManager.AppSettings["ClientId"].ToString(),
Authority = ConfigurationManager.AppSettings["Authority"].ToString(),
RedirectUri = ConfigurationManager.AppSettings["RedirectUri"].ToString();//https://www.example.com
使用https://example.com的用户出现上述异常。
为www.example.com 和example.com 生成的cookie 不同。所以在登录后重定向时,cookie不包含正确的nonce来验证并发生异常。
问题的解决方法是动态设置重定向URL
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
ClientId = ConfigurationManager.AppSettings["ClientId"].ToString(),
Authority = ConfigurationManager.AppSettings["Authority"].ToString(),
RedirectUri = ConfigurationManager.AppSettings["RedirectUri"].ToString(),//https://www.example.com
,
// sample how to access token on form (when adding the token response type)
Notifications = new OpenIdConnectAuthenticationNotifications
RedirectToIdentityProvider = async n =>
var uri = n.Request.Uri; //From request URL determine the RedirctUri and set below
n.ProtocolMessage.RedirectUri =""//Set the url here
https://www.example.com 和 http://www.example.com 可能会出现同样的问题
【讨论】:
【参考方案10】:对于 2021 年来到这里的其他人,如果出现以下情况,您可能会遇到此问题:
您正在重定向 http -> https 或者您更改了应用的主机域。这两个问题都不是中间件或您的应用程序的问题,而是两个问题的结合:
您的应用程序仍然托管在旧的旧域或协议上。您希望通过在 Web 服务器上实现重定向来防止浏览器遇到这种情况。 Azure 中的重定向 URI(有时称为回复 URL)或您正在使用的任何 OpenIdConnect 授权服务器进行身份验证。您希望将此更新到新的协议或域。我们的例子:我们有https://old.example.com/app/,现在也托管在https://new.example.com/app/。我们希望用户以前的书签仍然有效。
我们的解决方案:
-
我们更新了重定向 URI(回复 url)以指向应用程序的新域 (https://new.example.com/app/signin-endpoint)。理想情况下,请确保只为您的应用列出一个 URI,并且它是 https。
我们在 IIS 中为站点添加了新的域绑定(我们是老派,但对您选择的托管执行相同的操作?)
我们添加了一个 IIS 重定向到新域 (new.example.com),这样用户的书签仍然可以使用。同样,如果您不在 IIS 上,请在您选择的 Web 服务器中实现永久重定向。
在我们完成上述最后一步之前,我们在 OP 的帖子中看到了错误。如果您强制使用 http -> https,则过程相同。
这是为那些也是“老派”的人重新编写的 IIS:
<rewrite>
<rules>
<rule name="Redirect old.example.com to new.example.com" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions>
<add input="HTTP_HOST" pattern="old.example.com" />
</conditions>
<action type="Redirect" url="https://new.example.comREQUEST_URI" />
</rule>
</rules>
</rewrite>
它位于 web.config 文件的 <system.webServer>
部分。享受吧!
【讨论】:
+1 "你正在重定向 http -> https" --- 这成功了。我的 Azure AD 应用注册在回复 URL 中有错误的协议,http 不是 https【参考方案11】:当 Edge 设置为 IE 兼容模式时遇到此问题的用户,将其从 IE 兼容性中删除并解决了该问题。设置/站点列表由 edge://compat 控制。
【讨论】:
【参考方案12】:我最终允许 Owin 跳到 AuthentificationFaild 回调函数的下一个中间件。我正在检查错误消息是否包含 nonce 错误 Id 并从上下文中调用 SkipToNextMiddleware 函数。有了这个,我将重新启动登录过程,因此如果未设置用户 cookie,将会有第二个调用来设置 cookie。
代码是用vb.net写的
Dim oidcAuthOpt= New OpenIdConnectAuthenticationOptions()
oidcAuthOpt.Notifications = New OpenIdConnectAuthenticationNotifications With
.AuthenticationFailed = Function(n)
If (n.Exception.Message.StartsWith("OICE_20004") Or n.Exception.Message.Contains("IDX10311")) Then
n.SkipToNextMiddleware()
Return Task.FromResult(0)
End If
Return Task.FromResult(0)
End Function
【讨论】:
以上是关于OWIN OpenIdConnect 中间件 IDX10311 随机数无法验证的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Azure OpenIdConnect OWIN 中间件 Cookie Auth 转换为 SPA 应用程序的 JavaScript JWT?
在 OwinStartup 之后为新租户添加 Owin 管道中间件
Azure OpenID Connect 通过 OWIN 中间件导致无限重定向循环