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

时间:2016-04-22 13:30:50

标签: asp.net cookies oauth owin

我在C#ASP MVC Web应用程序中使用OWIN / OAuth和OpenId Connect身份验证(Microsoft.Owin.Security.OpenIdConnect)。使用Microsoft帐户登录SSO基本上有效,但我不时会在浏览器上显示Bad Request - Request Too Long的错误页面。

我发现这个错误是由太多的cookie引起的。删除cookie有一段时间了,但过了一段时间后问题又回来了。

导致问题的cookie是从OpenId框架设置的,因此有许多名称为OpenIdConnect.nonce.9oEtF53WxOi2uAw.......的cookie。

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

4 个答案:

答案 0 :(得分:36)

事实证明,根本原因是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权限)。

答案 1 :(得分:2)

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

复制步骤

  • 删除受保护页面上的ASP.NET_SessionId cookie和idsrv cookie 您的网络应用程序
  • 刷新页面
  • 重定向到OIDC身份验证存储并进行身份验证
  • 重定向回webapp =>身份验证失败, 因为没有可用的asp.net会话
  • 无休止的重定向,直到发生“请求时间过长...”错误

解决方案: 通过添加

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

至global.asax.cs。

答案 2 :(得分:0)

在我的情况下,问题是我在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...
    }

答案 3 :(得分:0)

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

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