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 文件的 &lt;system.webServer&gt; 部分。享受吧!

【讨论】:

+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?

支持 JWT 密钥轮换的承载令牌认证的 Owin 中间件

在 OwinStartup 之后为新租户添加 Owin 管道中间件

Azure OpenID Connect 通过 OWIN 中间件导致无限重定向循环

OpenID Connect 的 OWIN 中间件 - 代码流(流类型 - AuthorizationCode)文档?

Owin,在Authentication Request中传递自定义查询参数