无法验证 OWIN OpenIdConnect 中间件 IDX10311 nonce

OWIN OpenIdConnect Middleware IDX10311 nonce cannot be validated

我有一个使用 OpenIdConnect 的 OWIN 中间件的应用程序。 startup.cs 文件使用 app.UseOpenIdConnectAuthentication 的标准实现。 cookie 已设置到浏览器,但出现错误:

IDX10311: RequireNonce is 'true' (default) but validationContext.Nonce is null. A nonce cannot be validated. If you don't need to check the nonce, set OpenIdConnectProtocolValidator.RequireNonce to 'false'.

我发现当 运行ning fiddler 就像我对大多数调试项目所做的那样时,会发生这种行为。返回错误,但如果我返回该站点,一切正常并且我的用户已通过身份验证。 运行ning fiddler 时有人看到过这种行为吗?

使用提琴手:

运行 没有提琴手:

想法?我可以在没有 运行ning fiddler 的情况下绕过它,但是在调试时最好也 运行 fiddler 来检查流量。

也许是这个原因?

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

我正在总结我的发现:

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

  2. 一旦 OpenID 中间件启动身份验证会话,就会从应用程序设置此 cookie(我们称之为 "ID Client")

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

  4. 我的很多困惑是由 "Nonce" 术语引起的,它既用在这个 cookie 中,也用在来自 ID 服务器的 OpenID Connect 流中。

  5. 在我的例子中,异常是由丢失的 cookie(不是 ID 服务器的随机数)引起的,只是因为它没有被浏览器发送回 "ID client"

所以在我的例子中,主根是这样的:OpenIdConnect.nonce.OpenIdConnect浏览器没有将 cookie 发送回 ID 客户端。在某些情况下(即 Chrome、Firefox 和 Edge)cookie 被正确发送,而在其他情况下(IE11、Safari)则不是。

经过大量研究,我发现问题出在浏览器上定义的Cookie限制策略上。在我的例子中,"ID client" 嵌入在 <iframe> 中。这导致 "ID Client" 被视为 "third-party client",因为用户没有直接在主 window 中导航到那个 URL。因为这是第三方,所以对于某些浏览器,它的 cookie 必须被阻止。 实际上,通过设置 "Block third-party cookies".

,可以在 Chrome 上获得相同的效果

所以,我不得不得出结论:

a) 如果 iframe 是必须的(就像我的情况一样,因为 "ID Clients" 是必须 运行 在我们主要平台应用程序的图形内容中的应用程序),我认为唯一的解决方案就是拦截错误,用页面处理,要求用户启用第三方cookies。

b) 如果 iframe 不是必须的,在新的 window.

中打开 "ID Client" 就足够了

希望这对某人有所帮助,因为我疯了!

马可

我知道它是一个旧的 post 但我遇到了这个问题并且对我没有任何作用,在我失去了使我的企业应用程序正常工作的解决方案之后,我最终通过设置 multi-在 Azure 中将租户选项设置为是(在 Azure select 中:应用程序注册>设置>属性,将多租户设置为是并单击保存)。

希望它对某人有所帮助,没看到有人提到它。

我遇到了同样的问题,但将 Microsoft.Owin.Security.OpenIdConnect 切换回版本 3.0.1 解决了问题

当我切换到完整的 IIS 托管时,当 运行 IIS Express 在后台运行时,我注意到了这个错误。当我禁用 IIS Express 时,我的错误消失了。

对我来说,在 Azure 活动目录中更改回复 url 是可行的。

启用 SSL 时会发生这种情况,因为它仅将 URL 上的登录更改为 HTTPS URL,而回复 URL 保持不变的 HTTP URL。

当您尝试使用 https URL 访问您的应用程序时,它会在您的浏览器中设置一个具有唯一编号 (nonce) 的 cookie,并点击 Azure AD 进行身份验证。身份验证后,浏览器必须授予对该 cookie 的访问权限。但是由于 URL 上的登录和回复 URL 不同,浏览器无法识别您的应用程序并且无法访问该 cookie,因此应用程序会抛出此错误。

web.config 中的 cookie 重写规则以确保同站点 cookie 给出此神秘异常。禁用该规则解决了它。

对于通过 Azure Active Directory 保护的应用程序,对我有用的临时解决方案是注销(通过转到 sites/Account/SignOut 页面),然后我能够 return 到主页并登录确定。希望这对某人有所帮助。

我知道这件事已经有一段时间了。我的具体问题是与 IdentityServer 身份验证相关的 IDX10311 错误,而 Fiddler(流量检查器代理)是 运行。在主机名包含 "localhost" 的情况下,我添加了一个自定义的 owin 中间件来捕获和吸收 IDX13011。忽略此异常允许我们使用带有 fiddler 的站点作为解决方法。我认为这会导致身份验证过程中断,尽管我们必须在回调的浏览器地址栏中按回车键才能再次运行,但这只会影响开发。

下面是我们在中间件中用来吸收错误的invoke方法。我应该指出,我们偶尔也会在生产中看到这个错误。没有解释原因,但我感觉它与使用 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);
            }
        }
    }

对我来说这是一个不同的问题。我的网站正在使用下面的两个 urls

https://www.example.comhttps://example.com

但我的重定向 url 是 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 不包含正确的随机数来验证并发生异常。

问题的解决方法是动态设置重定向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

也会发生同样的问题

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

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

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

  • 您的应用程序仍托管在旧域或协议上的事实。您希望通过在 Web 服务器上实施重定向来防止浏览器点击它。
  • Azure 中的重定向 URI(有时称为回复 URL)或您要使用其进行身份验证的任何 OpenIdConnect 授权服务器。您想将其更新到新的协议或域。

我们的例子: 我们有 https://old.example.com/app/ that was now also hosted at https://new.example.com/app/。我们希望用户以前的书签仍然有效。

我们的解决方案:

  1. 我们更新了重定向 URI(回复 url)以指向应用程序的新域(https://new.example.com/app/signin-endpoint)。理想情况下,确保只为您的应用列出一个 URI,并且它是 https。
  2. 我们在 IIS 中添加了新的域绑定到站点(我们是老派,但对您选择的主机也这样做)
  3. 我们添加了到新域 (new.example.com) 的 IIS 重定向,以便用户的书签仍然有效。同样,如果您不在 IIS 上,请在您选择的 Web 服务器中实施永久重定向。

在完成上述最后一步之前,我们一直在 OP post 中看到错误。如果您强制使用 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 文件的 <system.webServer> 部分。享受吧!

用户在将 Edge 设置为 IE 兼容模式时遇到此问题,将其从 IE 兼容性中删除并解决了该问题。站点设置/列表在 edge://compat.

下控制

我最终允许 Owin 在 AuthentificationFaild 回调函数上跳到下一个中​​间件。我正在检查错误消息是否包含随机数错误 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
       }