太多 cookie OpenIdConnect.nonce 导致错误页面 "Bad Request - Request Too Long"
Too many cookies OpenIdConnect.nonce cause error page "Bad Request - Request Too Long"
我在 C# ASP MVC 网络应用程序中使用带有 OpenId Connect 身份验证 (Microsoft.Owin.Security.OpenIdConnect
) 的 OWIN/OAuth。使用 Microsoft 帐户的 SSO 登录基本上可以工作,但有时我会在浏览器上收到一个错误页面,上面写着 Bad Request - Request Too Long
.
我发现这个错误是由太多的cookies引起的。删除 cookie 有一段时间有帮助,但过一会儿问题又回来了。
导致问题的cookies是从OpenId框架设置的,所以有几十个名字像OpenIdConnect.nonce.9oEtF53WxOi2uAw.......
.
的cookies
这不是 SPA 应用程序,但某些部分会通过 ajax 调用定期刷新。
原来根本原因是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 权限)。
在我的例子中,问题是我在 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...
}
对我来说,解决方案是强制创建 ASP.NET 会话。
重现步骤:
- 删除受保护页面上的ASP.NET_SessionId cookie 和 idsrv cookie
你的网络应用
- 重新加载页面
- 重定向到 OIDC 身份验证存储并进行身份验证
- 重定向回 webapp => 身份验证验证失败,
因为没有 asp.net 会话可用
- 无限重定向直到 'Request too long...' 错误发生
解决方法:
通过添加
强制创建会话
protected void Session_Start(object sender, EventArgs e)
{
}
至global.asax.cs。
OWIN 和 MVC 可能正在删除彼此的 cookie,如 AspNetKatana github 所述。
- 作为该页面建议明确使用
SystemWebCookieManager
或 SystemWebChunkingCookieManager
(Microsoft.Owin.Host.SystemWeb 3.1.0) 的解决方法。
- 还有 Kentor Owin Cookie Saver 作为解决方法。
- 但是,我会先尝试升级到 Owin 4.1.0(2019 年 11 月发布),因为这似乎可以解决问题![=21=]
我在 C# ASP MVC 网络应用程序中使用带有 OpenId Connect 身份验证 (Microsoft.Owin.Security.OpenIdConnect
) 的 OWIN/OAuth。使用 Microsoft 帐户的 SSO 登录基本上可以工作,但有时我会在浏览器上收到一个错误页面,上面写着 Bad Request - Request Too Long
.
我发现这个错误是由太多的cookies引起的。删除 cookie 有一段时间有帮助,但过一会儿问题又回来了。
导致问题的cookies是从OpenId框架设置的,所以有几十个名字像OpenIdConnect.nonce.9oEtF53WxOi2uAw.......
.
这不是 SPA 应用程序,但某些部分会通过 ajax 调用定期刷新。
原来根本原因是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 权限)。
在我的例子中,问题是我在 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...
}
对我来说,解决方案是强制创建 ASP.NET 会话。
重现步骤:
- 删除受保护页面上的ASP.NET_SessionId cookie 和 idsrv cookie 你的网络应用
- 重新加载页面
- 重定向到 OIDC 身份验证存储并进行身份验证
- 重定向回 webapp => 身份验证验证失败, 因为没有 asp.net 会话可用
- 无限重定向直到 'Request too long...' 错误发生
解决方法: 通过添加
强制创建会话protected void Session_Start(object sender, EventArgs e)
{
}
至global.asax.cs。
OWIN 和 MVC 可能正在删除彼此的 cookie,如 AspNetKatana github 所述。
- 作为该页面建议明确使用
SystemWebCookieManager
或SystemWebChunkingCookieManager
(Microsoft.Owin.Host.SystemWeb 3.1.0) 的解决方法。 - 还有 Kentor Owin Cookie Saver 作为解决方法。
- 但是,我会先尝试升级到 Owin 4.1.0(2019 年 11 月发布),因为这似乎可以解决问题![=21=]