ASP.NET_SessionId + OWIN Cookies do not send to browser 直译为:ASP.NET_SessionId + OWIN Cookies 不会发送到浏览器。

15 浏览
0 Comments

ASP.NET_SessionId + OWIN Cookies do not send to browser 直译为:ASP.NET_SessionId + OWIN Cookies 不会发送到浏览器。

我在使用Owin cookie身份验证时遇到了一个奇怪的问题。\n当我启动我的IIS服务器时,IE/Firefox和Chrome上的身份验证都正常工作。\n我开始在不同的平台上进行身份验证和登录的测试,结果出现了一个奇怪的错误。间断性地,Owin框架/IIS就是不向浏览器发送任何cookie。我会输入正确的用户名和密码,代码运行正常,但浏览器根本没有收到任何cookie。如果我重启服务器,它就会开始工作,然后在某个时候尝试登录时,cookie再次停止传递。跳过代码也没有任何效果,也没有抛出任何错误。\n在我的登录过程中,我有以下代码:\nIAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;\nauthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);\nvar authentication = HttpContext.Current.GetOwinContext().Authentication;\nvar identity = new ClaimsIdentity(\"ABC\");\nidentity.AddClaim(new Claim(ClaimTypes.Name, user.Username));\nidentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.User_ID.ToString()));\nidentity.AddClaim(new Claim(ClaimTypes.Role, role.myRole.ToString()));\nauthentication.AuthenticationResponseGrant =\n new AuthenticationResponseGrant(identity, new AuthenticationProperties()\n {\n IsPersistent = isPersistent\n });\nauthenticationManager.SignIn(new AuthenticationProperties() {IsPersistent = isPersistent}, identity);\n更新1:看起来问题的一个原因是当我添加项目到会话时问题开始出现。添加一些简单的内容,比如Session.Content[\"ABC\"]= 123似乎会导致问题。\n我能理解的情况如下:\n1)(Chrome)当我登录时,我得到了ASP.NET_SessionId和我的身份验证cookie。\n2)我转到一个设置session.contents的页面...\n3)打开一个新的浏览器(Firefox)并尝试登录,它既没有收到ASP.NET_SessionId,也没有收到身份验证cookie。\n4)当第一个浏览器有ASP.NET_SessionId时,它仍然工作。一旦我删除这个cookie,它就和其他所有浏览器一样有同样的问题。\n我正在使用IP地址(10.x.x.x)和本地主机。\n更新2:在使用OWIN进行身份验证之前,强制首先创建ASPNET_SessionId在我的login_load页面上。\n1)在我使用OWIN进行身份验证之前,我在我的登录页面上创建一个随机的Session.Content值来启动ASP.NET_SessionId。\n2)然后我进行身份验证并创建更多的会话。\n3)其他浏览器现在似乎可以工作。\n这很奇怪。我只能得出这样的结论,这与ASP和OWIN认为它们处于不同的域有关。\n更新3 - 两者之间的奇怪行为。\n额外的奇怪行为被识别出来 - Owin和ASP会话的超时时间不同。我看到的情况是,我的Owin会话比我的ASP会话通过某种机制保持更长时间的活动。所以当登录时:\n1.)我有一个基于cookie的身份验证会话\n2.)我设置了一些会话变量\n我的会话变量(2个)在OWIN cookie会话变量强制重新登录之前“死亡”,这导致我的整个应用程序中出现意外行为(人被登录但实际上没有登录)。\n更新3B\n经过一些调查,我看到有人在一个页面上说“forms”身份验证超时和会话超时需要匹配。我认为通常情况下,两者是同步的,但由于某种原因,两者不同步。\n解决方法摘要\n1)在身份验证之前始终先创建一个会话。基本上在启动应用程序时创建会话Session[\"Workaround\"] = 0;\n2)[实验性]如果您持久化cookie,请确保您的OWIN超时/长度比web.config中的sessionTimeout更长(在测试中)

0
0 Comments

问题出现的原因是System.Web和Owin有各自独立的cookie信息源,System.Web使用的是Set-Cookie头部信息,而Owin只知道Set-Cookie头部信息。解决方法是确保Owin设置的cookie也在HttpContext.Current.Response.Cookies集合中设置。可以使用一个名为Kentor.OwinCookieSaver的中间件来实现这一点。在中间件注册之前,使用app.UseKentorOwinCookieSaver()方法将其激活。具体代码如下:

app.UseKentorOwinCookieSaver();

app.UseCookieAuthentication(new CookieAuthenticationOptions());

除了安装该包,你还需要在Startup.Auth.cs文件中使用app.UseKentorCookieMiddlewareSaver()方法来激活它。这样做还可以处理注销时的cookie清除问题。

另外,注意到上述评论中的代码有误,正确的代码应该是app.UseKentorOwinCookieSaver()。这个问题已经在GitHub页面上得到修正。

另外,有用户遇到了在通过Meetup进行注册时,AuthenticationManager.GetExternalLoginInfoAsync()方法返回null的问题。然而,上述NuGet包并没有解决这个问题。为了解决这个问题,可以显式地注销应用程序cookie,使用authenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie)方法。

以上是关于“ASP.NET_SessionId + OWIN Cookies do not send to browser”问题的原因和解决方法的整理。

0
0 Comments

问题的出现原因是.NET cookie管理器会覆盖在OWIN层设置的cookie。解决方法是使用SystemWebCookieManager类,该类可以强制OWIN使用.NET cookie管理器以消除不一致性。

在应用程序启动时,只需在创建OWIN依赖项时分配它:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    ...
    CookieManager = new SystemWebCookieManager()
    ...
});

此外,还提供了一个类似的解决方案,但未包含解决问题所需的所有代码,因此在这里添加了完整的解决方案。

感谢,这对我很有帮助,但我还通过在externallogincallback函数中调用ControllerContext.HttpContext.Session.RemoveAll()来清除所有会话。

这适用于ASP.NET Webforms 4.6.1吗?我的Web应用程序使用了ASP.NET Webforms、OWIN和ADFS。

你的Web应用程序使用OWIN cookies吗?如果是这样,那么是的。

在代码Startup.ConfigureAuth中,我们有app.UseCookieAuthentication和app.UseWsFederationAuthentication,最后是app.UseStageMarker。

你可能要考虑进行编辑,我的团队遇到了这个bug,它是稀有且随机的,在开发和UAT环境中我们都没有发现。你的答案中的这句话没有对我们起作用:“.NET cookie管理器总是会胜出。”如果OWIN cookies总是被覆盖,我们的OIDC中间件就不会从我们的开发工作站迁移到其他地方。但这个bug的随机性意味着它在生产环境中持续存在了两天,直到我们的规模问题暴露出来(我们一半的内部用户无法通过AAD登录)。你介意我在你的答案中删除“总是”这个词吗?

但你能解释一下为什么吗?

我修改了答案,但我想真正的问题是在什么情况下,.NET cookie管理器不会胜过OWIN的?

我唯一的答案是“规模”。我们使用AAD仅有一个月的时间,就发现我们的最大客户之一在他们的防火墙中阻止了AAD登录所使用的三个顶级域名之一,并且不得不彻底更换另一个身份验证提供者的实现。

我尝试了这个线程中的所有方法。只有当Fiddler打开时,它才对我起作用。似乎Fiddler在代码中做了一些其他的事情。有什么建议吗?

听起来你遇到的是你和服务器之间的不受信任的SSL证书。Fiddler添加了一个中间件,它创建了自己的CA证书,并为每个连接签名新的证书,因此当Fiddler运行时,你的计算机可能信任服务器,但在其他情况下不信任它。

我认为我遇到了同样的问题,我尝试了你的解决方案,但没有起作用。我使用的是.NET 4.6和OWIN,这个方法还适用吗?有人有什么想法吗?

我不确定,但https://github.com/aspnet/AspNetKatana/wiki/System.Web-response-cookie-integration-issues中提到:这个问题已经在下一个版本的Katana(ASP.NET Core)中得到解决,其中响应cookie的存储已经标准化为始终存储在响应标头集合中。

使用Microsoft.Owin.Host.SystemWeb中的SystemWebCookieManager和SystemWebChunkingCookieManager代替你自己的代码副本。

0
0 Comments

ASP.NET_SessionId和OWIN Cookies不发送到浏览器的问题出现的原因是OWIN ASP.NET托管实现的一个bug。OWIN使用自己的抽象来处理响应Cookies,而ASP.NET也使用自己的抽象来处理响应Cookies。在请求生命周期的晚期,ASP.NET会检测到响应Cookies的状态是否发生了变化,并将Cookies序列化到Set-Cookie头部。然而,OWIN直接更改了响应的Set-Cookie头部,导致ASP.NET的状态检测失效,从而导致OWIN Cookies丢失。

解决这个问题的方法是在用户进行身份验证之前设置Session。这样一来,ASP.NET_SessionId会在System.Web.HttpResponse.Cookies集合中添加,并且Set-Cookie头部不会被清除。这样,OWIN认证的Cookies和ASP.NET_SessionId都会在响应中发送,身份验证就可以正常工作。

这个问题的根源在于OWIN ASP.NET托管实现和ASP.NET自身对响应Cookies的处理方式不一致,导致状态检测失效。只要在身份验证之前设置Session,就可以解决这个问题。但需要注意,如果直接使用System.Web.HttpResponse.Cookies集合,也会导致OWIN Cookies丢失。因此,在使用OWIN时,应尽量避免直接操作System.Web.HttpResponse.Cookies集合。

这个问题已经被报告给了katanaproject,并且得到了一些评论。但据称,这个问题要等到vNext版本才会被修复,这被认为不够及时。

此外,还有一些用户在使用Controller.TempData或者System.Web.SessionState.SessionStateModule时也遇到了类似的问题。这些问题可能与Session相关的优化机制有关,但具体原因还需要进一步的调查。

ASP.NET_SessionId和OWIN Cookies不发送到浏览器的问题是由于OWIN ASP.NET托管实现和ASP.NET自身对响应Cookies的处理方式不一致导致的。解决这个问题的方法是在身份验证之前设置Session,并避免直接操作System.Web.HttpResponse.Cookies集合。希望这个问题能够尽快得到修复,以提高用户体验。

0