【问题标题】:OWIN OpenIdConnect Middleware IDX10311 nonce cannot be validatedOWIN OpenIdConnect 中间件 IDX10311 随机数无法验证
【发布时间】: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 来检查流量。

【问题讨论】:

  • 谢谢布洛克。我过去看过那个线程。对许多人来说,这似乎是一个未解决的问题。不过,我会从帖子中查看您的建议。我希望这不是 MS Katana 错误,尽管正如 Dominick 所建议的那样,因为 MS 已经有一段时间没有更新该 nuget 包了。
  • @gilm0079 你找到解决办法了吗?

标签: c# owin fiddler identityserver3 openid-connect


【解决方案1】:

也许是这个原因?

你好,我想我找到了这个问题的根本原因。

我正在总结我的发现:

  1. 问题出在 OpenIdConnect.nonce.OpenIdConnect cookie 中

  2. 只要 OpenID 中间件启动身份验证会话,就会从应用程序(我们称之为“ID 客户端”)设置此 cookie

  3. 身份验证完成后,cookie 应立即从浏览器发送回“ID 客户端”。我的假设是,从 ID 客户端的角度来看,需要对这个 cookie 进行仔细检查(即我是否真的启动了 OpenID Connect 授权流程?)

  4. 我的很多困惑是由“Nonce”术语引起的,该术语在此 cookie 和来自 ID 服务器的 OpenID Connect 流中都使用过。

  5. 在我的例子中,异常是由缺少 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.comhttps://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.comhttp://www.example.com 可能会出现同样的问题

          【讨论】:

            【解决方案10】:

            对于 2021 年来到这里的其他人,如果出现以下情况,您可能会遇到此问题:

            • 您正在重定向 http -> https
            • 或者您更改了应用的主机域。

            这两个问题都不是中间件或您的应用程序的问题,而是两个问题的结合:

            • 您的应用程序仍然托管在旧的旧域或协议上。您希望通过在 Web 服务器上实现重定向来防止浏览器遇到这种情况。
            • Azure 中的重定向 URI(有时称为回复 URL)或您正在使用的任何 OpenIdConnect 授权服务器进行身份验证。您希望将此更新到新的协议或域。

            我们的例子:我们有https://old.example.com/app/,现在也托管在https://new.example.com/app/。我们希望用户以前的书签仍然有效。

            我们的解决方案:

            1. 我们更新了重定向 URI(回复 url)以指向应用程序的新域 (https://new.example.com/app/signin-endpoint)。理想情况下,请确保只为您的应用列出一个 URI,并且它是 https。
            2. 我们在 IIS 中为站点添加了新的域绑定(我们是老派,但对您选择的托管执行相同的操作?)
            3. 我们添加了一个 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.com{REQUEST_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
                     }
              

              【讨论】:

                猜你喜欢
                • 2015-08-19
                • 2021-10-11
                • 2021-12-21
                • 2015-05-08
                • 1970-01-01
                • 1970-01-01
                • 2019-12-24
                • 2017-08-20
                • 1970-01-01
                相关资源
                最近更新 更多