OWIN OpenIdConnect中间件IDX10311随机数无法验证

时间:2016-09-09 13:22:09

标签: c# owin fiddler identityserver3 openid-connect

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

  

IDX10311:RequireNonce是' true' (默认值)但validationContext.Nonce为null。 nonce无法验证。如果您不需要检查现时,请将OpenIdConnectProtocolValidator.RequireNonce设置为' false'。

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

用小提琴手:

  • OpenIdConnect中的SecurityTokenValidated通知执行两次。
  • 第二次通过IDX10311错误后抛出
  • 浏览器包含有效的cookie,返回页面我可以查看有效的User.Identity数据。

没有fiddler跑步:

  • SecurityTokenValidated在OpenIdConnect
  • 中执行一次
  • 没有抛出任何错误,继续加载控制器操作以进行后验证重定向Uri
  • Cookie也有效且User.Identity数据正确。

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

11 个答案:

答案 0 :(得分:5)

这可能是原因吗?

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

我总结了我的发现:

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

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

  3. 一旦验证完成,cookie就应该从浏览器发送回“ID Client”。我的假设是需要这个cookie从ID客户端的角度进行双重检查(即我真的开始了OpenID Connect授权流程吗?)

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

  5. 在我的情况下,例外是由于丢失的cookie(不是ID服务器的nonce)引起的,只是因为它没有被浏览器发送回“ID客户端”

  6. 因此,在我的情况下,主根是这样的:浏览器没有将OpenIdConnect.nonce.OpenIdConnect cookie发送回ID Client。在某些情况下(例如Chrome,Firefox和Edge)cookie正确发送,而在其他情况下(IE11,Safari)则没有。

    经过大量研究后,我发现问题出在浏览器上定义的Cookie限制策略中。就我而言,“ID客户端”嵌入在<iframe>中。这导致“ID客户端”被视为“第三方客户端”,因为用户没有直接在主窗口中导航到该URL。因为这是第三方,对于某些浏览器,它的cookie必须被阻止。 实际上,通过设置“阻止第三方cookie”,可以在Chrome上获得相同的效果。

    所以,我必须得出结论:

    a)如果iframe是必须的(在我的情况下,因为“ID客户端”是必须在我们的主平台应用程序的图形内容中运行的应用程序),我认为唯一的解决方案是拦截错误,并且用页面处理它,要求用户启用第三方cookie。

    b)如果iframe不是必须的,那么就足以在新窗口中打开“ID Client”。

    希望这有助于某人,因为我疯了!

答案 1 :(得分:5)

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

答案 2 :(得分:2)

我知道这是一个老帖子,但是我遇到了这个问题,没有什么对我有用,在我的企业应用程序工作的解决方案背后失去理智后我最终通过在天蓝色中设置多租户选项来修复它(在Azure中选择:app registration&gt; settings&gt; properties,将multi-tenanted设置为yes并单击save)。

希望它对某人有所帮助,看不到任何人提及它。

答案 3 :(得分:1)

对于我来说,更改Azure活动目录中的回复网址。

当您启用SSL时会发生这种情况,因为它只会更改HTTPS URL的登录URL,而回复URL仍然是相同的HTTP URL。

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

答案 4 :(得分:1)

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

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

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

  • 您的应用仍托管在旧的旧域或协议上的事实。您希望通过在 Web 服务器上实现重定向来防止浏览器访问该地址。
  • Azure 或任何 OpenIdConnect 授权服务器中的重定向 URI(有时称为回复 URL)。您希望将其更新为新协议或域。

我们的示例:我们的 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. 我们向新域 (new.example.com) 添加了一个 IIS 重定向,以便用户的书签仍然有效。同样,如果您不在 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 文件的 <system.webServer> 部分。享受!

答案 5 :(得分:0)

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

答案 6 :(得分:0)

web.config中的cookie重写规则,以确保相同站点的cookie给出了这种神秘的异常。禁用该规则即可解决。

答案 7 :(得分:0)

一个对我有效的适用于通过Azure Active Directory保护的应用程序的临时解决方案是注销(通过转到网站/帐户/注销页面),然后我可以返回主页并成功登录。希望这对某人有帮助。

答案 8 :(得分:0)

我知道这已经有一段时间了。我的特定问题是与Fiddler(流量检查器代理)运行时通过IdentityServer进行身份验证有关的IDX10311错误。我添加了一个定制的owin中间件,以在主机名包含“ localhost”的情况下捕获并吸收IDX13011。忽略此异常,使我们可以将网站与fiddler一起使用来解决。我认为这会导致身份验证过程中断,尽管我们必须在回调的浏览器地址栏中按Enter才能再次进行,但这只会影响开发。

这是我们在中间件中用来吸收错误的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);
            }
        }
    }

答案 9 :(得分:0)

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

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 不包含要验证的正确随机数,并且会发生异常。

问题的解决方法是动态设置重定向网址

  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 :(得分:0)

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