cookie 过多 OpenIdConnect.nonce 导致错误页面“错误请求 - 请求太长”

Posted

技术标签:

【中文标题】cookie 过多 OpenIdConnect.nonce 导致错误页面“错误请求 - 请求太长”【英文标题】:Too many cookies OpenIdConnect.nonce cause error page "Bad Request - Request Too Long" 【发布时间】:2016-08-16 04:03:49 【问题描述】:

我在 C# ASP MVC Web 应用程序中使用 OWIN / OAuth 和 OpenId Connect 身份验证 (Microsoft.Owin.Security.OpenIdConnect)。使用 Microsoft 帐户进行 SSO 登录基本上可以正常工作,但有时我会在浏览器上收到一个错误页面,上面写着 Bad Request - Request Too Long

我发现这个错误是由太多的cookies引起的。删除 cookie 会有所帮助,但过一段时间问题又会出现。

导致问题的 cookie 是从 OpenId 框架中设置的,所以有几十个 cookie,名称类似于 OpenIdConnect.nonce.9oEtF53WxOi2uAw.......

这不是 SPA 应用程序,但某些部分会通过 ajax 调用定期刷新。

【问题讨论】:

【参考方案1】:

事实证明,根本原因是 Ajax 调用。

有问题的流程是

1) OAuth cookie 在一段时间后过期

2) 过期通常会导致页面重定向到login.microsoft.com 以刷新cookie。在这一步中,OAuth 框架添加新的 nonce cookie 到响应(每次)!

3) 但是 Ajax 不处理域外的重定向(跨域到login.microsoft.com)。但是 cookie 已经附加到页面上。

4) 下一次定期 Ajax 调用重复了导致“nonce”cookie 快速增加的流程。

解决方案

我不得不扩展“OWIN OpenId”框架设置代码以不同方式处理 Ajax 调用 - 以防止重定向和停止发送 cookie。

public void ConfigureAuth(IAppBuilder app)

    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        
            ClientId = clientId,
            Authority = authority,
            Notifications = new OpenIdConnectAuthenticationNotifications
            
                RedirectToIdentityProvider = ctx => 
                
                    bool isAjaxRequest = (ctx.Request.Headers != null && ctx.Request.Headers["X-Requested-With"] == "XMLHttpRequest");

                    if (isAjaxRequest)
                    
                        ctx.Response.Headers.Remove("Set-Cookie");
                        ctx.State = NotificationResultState.HandledResponse;
                    

                    return Task.FromResult(0);
                
            
        );

也必须调整 Ajax 调用程序以检测 401 代码并执行整页刷新(这会导致快速重定向到 Microsoft 权限)。

【讨论】:

谢谢。我遇到了类似的问题,这有助于解决它。 一旦我清除了 chrome cookie,这似乎也解决了我的问题。具有讽刺意味的是,MS 勇敢的新浏览器 Edge.... 与 IE 一样存在许多不一致和性能问题,所以我现在又开始使用 chrome。 也解决了我的问题。谢谢【参考方案2】:

对我来说,解决方案是强制创建 ASP.NET 会话。

复制步骤

删除受保护页面上的 ASP.NET_SessionId cookie 和 idsrv cookie 你的 webapp 重新加载页面 重定向到 OIDC 身份验证存储并进行身份验证 重定向回 webapp => 验证验证失败, 因为没有可用的 asp.net 会话 无限重定向,直到出现“请求太长...”错误

解决方案: 通过添加

来强制创建会话
protected void Session_Start(object sender, EventArgs e)


到 global.asax.cs。

【讨论】:

【参考方案3】:

OWIN 和 MVC 可能正在删除彼此的 cookie,如 AspNetKatana github 所述。

作为一种解决方法,该页面建议明确使用SystemWebCookieManagerSystemWebChunkingCookieManager (Microsoft.Owin.Host.SystemWeb 3.1.0)。 还有Kentor Owin Cookie Saver 作为解决方法。 但是,我会先尝试升级到 Owin 4.1.0(2019 年 11 月发布),因为这似乎可以解决问题!

【讨论】:

【参考方案4】:

就我而言,问题是我在Startup.cs 中配置应用程序的顺序。

提醒自己 - 始终先配置身份验证!

public class Startup

    public void Configuration(IAppBuilder app)
    
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            
                ClientId = _clientId,
                ClientSecret = _clientSecret,
                Authority = _authority,
                RedirectUri = _redirectUri
            );

        // configure the rest of the application...
    

【讨论】:

以上是关于cookie 过多 OpenIdConnect.nonce 导致错误页面“错误请求 - 请求太长”的主要内容,如果未能解决你的问题,请参考以下文章

jmeter的http cookies管理器使用

Session与Cookie的区别

cookie和session的区别

cookie和session的区别

Cookie和Session的区别

asp.net判断用户登录错误次数3次,就不能在登陆了!