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

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

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

我发现当我像大多数调试项目一样运行fiddler时,就会出现这种情况。虽然返回了错误,但如果我回到网站,一切都正常工作,并且我的用户已通过身份验证。有人在运行fiddler时看到过这种情况吗?
使用fiddler时:
  • 在OpenIdConnect中,SecurityTokenValidated通知执行两次。
  • 第二次经过后,抛出IDX10311错误
  • 浏览器包含有效的cookie,返回页面后可以查看有效的User.Identity数据。
不使用fiddler时:
  • 在OpenIdConnect中,SecurityTokenValidated只执行一次
  • 没有抛出错误,继续加载控制器操作以进行后身份验证重定向Uri
  • cookie也有效,User.Identity数据正确。
有什么想法吗?我可以避开它而不运行fiddler,但调试时同时运行fiddler检查流量也很好。

可能是这个吗?https://github.com/IdentityServer/IdentityServer3/issues/542 - Brock Allen
谢谢Brock。我之前就看过那个帖子。看起来对于很多人来说,这仍然是一个未解决的问题。不过,我会查看一下你在帖子中提到的建议。我希望这不是MS Katana的错误,因为Dominick建议MS已经有一段时间没有更新那个nuget包了。 - gilm0079
1
@gilm0079,你找到解决方案了吗? - Brent Schmaltz
12个回答

12

也许这就是原因?

你好,我认为我找到了此问题的根本原因。

我总结了我的发现:

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

  2. 这个 cookie 是从应用程序(我们称之为“ID客户端”)中设置的,一旦 OpenID 中间件初始化了身份验证会话。

  3. 认证完成后,应该立即将 cookie 从浏览器发送回 “ID客户端”。 我的假设是, 这个 cookie 是需要从 ID 客户端的角度进行双重确认的 (例如:我是否真的开始了 OpenID Connect 授权流程?)

  4. 在这个 cookie 和 ID 服务器的 OpenID Connect 流程中都使用了“Nonce”术语,这给我带来了很多困惑。

  5. 在我的情况下,异常是由于缺少 cookie (而不是 ID 服务器的 nonce) 引起的,因为浏览器没有将其发送回“ID客户端”。

因此,在我的情况下,主要根源是:OpenIdConnect.nonce.OpenIdConnect cookie 没有被浏览器发送回 ID 客户端。在某些情况下(例如 Chrome、Firefox 和 Edge),cookie 被正确发送,而在其他情况下(IE11、Safari)则没有。

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

因此,我必须得出结论:

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

b) 如果不必使用iframe,则在新窗口中打开“ID Client”应该足够了。

希望这能帮助到某些人,因为我已经疯了!

马可


撤销我的评论。我在考虑另一个ID服务器问题。尽管你的答案似乎与我看到的不同,但它似乎是关于其他事情的。我的问题只是在调试项目时运行Fiddler进行流量检查时才会出现。否则它可以正常工作。 - gilm0079
1
对我来说,这似乎是一个浏览器问题。IE11重现了这个问题,而FF没有。感谢您的建议。 - Vladislav

7

我曾经遇到同样的问题,但是将Microsoft.Owin.Security.OpenIdConnect版本切换回3.0.1就解决了这个问题。


1
针对本地/测试环境版本>3.0.1无法正常工作,我认为这可能与伪造的SSL证书有关。然而,对于真实的SSL证书,版本>3.0.1似乎可以正常工作。 - Box Very

6

对于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. 我们在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文件的<system.webServer>部分。享受!


2
+1 "你正在重定向 http -> https" --- 这就是解决问题的方法。我的 Azure AD 应用程序注册在回复 URL 中使用了错误的协议,应该是 https 而不是 http。 - Glenn Ferrie

3

我知道这是一篇旧文章,但我遇到了这个问题,什么都对我没用。在我为解决企业应用程序的工作而疯狂的过程中,我最终通过在 Azure 中将多租户选项设置为“是”来解决它(在 Azure 中选择:应用注册>设置>属性,将多租户设置为“是”,然后单击保存)。

希望能帮助别人,之前没有人提到过这个方法。


3
对我来说,在Azure活动目录中更改回复URL是有效的。
这是因为启用SSL会将登录URL仅更改为HTTPS URL,而回复URL仍保持原有的HTTP URL。
当您尝试使用https URL访问应用程序时,它会在浏览器中设置一个带有唯一数字(nonce)的cookie,并向Azure AD请求进行身份验证。身份验证后,浏览器必须授予该cookie的访问权限。但由于登录URL和回复URL不同,浏览器无法识别您的应用程序,也无法授予该cookie的访问权限,因此应用程序会抛出此错误。

1
我们遇到了相同的问题。问题本身与Azure无关,而是与OpenIdConnect中间件处理http和https重定向url的方式有关。 - neleus
但是,我如何在不禁用SSL的情况下解决这个问题呢? - Heinzlmaen
@Heinzlmaen,您不需要禁用SSL。您需要相应地更改Azure AAD中的回复URL。 - Ashutosh B Bodake
你如何更改AAD中的回复?在哪里?从什么到什么?此外,AAD是一个企业关注点,但故障可能属于单个应用程序,而不是所有应用程序。 - zameb

1

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


这也是我的解决方法,除此之外,我还将IIS Express证书(位于IIS中)添加到了IIS中默认网站的https绑定中,然后我使用了所有的https流量,即使是本地主机,这样就解决了问题。 - smoore4

0

对我来说,这是一个不同的问题。我的网站可以使用以下两个URL同时工作

https://www.example.com and https://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 不包含正确的 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


0
在 web.config 中设置 cookies 重写规则以确保 samesite cookies 时,出现了这个神秘的异常。禁用该规则解决了问题。

2
你能详细说明那是什么意思吗? - jrummell

0
一个临时解决方案,在我的 Azure Active Directory 安全保护的应用中,是通过登出(前往 sites/Account/SignOut 页面)然后我就能够返回主页并成功登录。希望这对某人有所帮助。

0

当Edge设置为IE兼容模式时,用户会遇到此问题。将其从IE兼容性中移除即可解决该问题。站点的设置/列表受edge://compat控制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接