本文介绍了ASP.NET_SessionId + OWIN Cookie不会发送到浏览器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的问题,使用Owin Cookie身份验证。

I have a strange problem with using Owin cookie authentication.

当我开始我的IIS服务器的认证工作完全正常的IE / Firefox和Chrome。

When i start my IIS server authentication works perfectly fine on IE/Firefox and Chrome.

我开始做一些测试与认证,并在不同平台上登录,我已经想出了一个奇怪的错误。偶尔的Owin框架/ IIS只是不发送任何cookie的浏览器。我输入用户名和密码,这是正确的code运行,但没有饼干被交付给浏览器的。如果我重新启动服务器,它开始工作,然后在某个时候我会尝试登录,再次饼干停止获取交付。步进超过code什么都不做,不引发错误。

I started doing some testing with Authentication and logging in on different platforms and i have come up with a strange error. Sporadically the Owin framework / IIS just doesn't send any cookies to the browsers. I will type in a username and password which is correct the code runs but no cookie gets delivered to the browser at all. If i restart the server it starts working then at some point i will try login and again cookies stop getting delivered. Stepping over the code does nothing and throws no errors.

 app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationMode = AuthenticationMode.Active,
            CookieHttpOnly = true,
            AuthenticationType = "ABC",
            LoginPath = new PathString("/Account/Login"),
            CookiePath = "/",
            CookieName = "ABC",
            Provider = new CookieAuthenticationProvider
               {
                  OnApplyRedirect = ctx =>
                  {
                     if (!IsAjaxRequest(ctx.Request))
                     {
                        ctx.Response.Redirect(ctx.RedirectUri);
                     }
                 }
               }
        });

我的登录过程中我有以下code:

IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                            authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

var authentication = HttpContext.Current.GetOwinContext().Authentication;
var identity = new ClaimsIdentity("ABC");
identity.AddClaim(new Claim(ClaimTypes.Name, user.Username));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.User_ID.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Role, role.myRole.ToString()));
   authentication.AuthenticationResponseGrant = new AuthenticationResponseGrant(identity, new AuthenticationProperties()
                                                                                                                       {
                                                                                                                           IsPersistent = isPersistent

                                                                                                                       });

authenticationManager.SignIn(new AuthenticationProperties() {IsPersistent = isPersistent}, identity)

更新1:看来,问题的原因之一是,当我将项目添加到会话中的问题开始。添加像Session.Content [ABC] = 123简单的东西似乎产生了问题。

Update 1: It seems that one cause of the problem is when i add items to session the problems start. Adding something simple like Session.Content["ABC"]= 123 seems to create the problem.

我可以做出来如下:
1)(铬)当我登录我得到ASP.NET_SessionId +我的身份验证cookie。
2)我去那台session.contents一个网页...
3)打开一个新的浏览器(Firefox),并尝试登录,并没有收到ASP.NET_SessionId也没有得到验证cookie
4)虽然在第一浏览器具有ASP.NET_SessionId它继续工作。我删除这个cookie一刻它有同样的问题,因为所有其他浏览器
我工作的IP地址(10.x.x.x)和本地主机。

What i can make out is as follows:1) (Chrome)When i login i get ASP.NET_SessionId + my authentication cookie.2) I go to a page that sets a session.contents...3) Open a new browser (Firefox) and try login and it does not receive an ASP.NET_SessionId nor does it get a Authentication Cookie4) Whilst the first browser has the ASP.NET_SessionId it continues to work. The minute i remove this cookie it has the same problem as all the other browsersI am working on ip address (10.x.x.x) and localhost.

更新2:力创造ASPNET_SessionId的第一与OWIN验证之前,我login_load页面。

Update 2: Force creation of ASPNET_SessionId first on my login_load page before authentication with OWIN.

1)之前,我与OWIN身份让我的登录页面,启动ASP.NET_SessionId一个随机值Session.Content
2)然后我进行身份验证并做进一步的会议
3)其他浏览器似乎现在的工作。

1) before i authenticate with OWIN i make a random Session.Content value on my login page to start the ASP.NET_SessionId2) then i authenticate and make further sessions3) Other browsers seem to now work

这是奇怪的。我只能说这事做ASP和OWIN思考他们在不同的域或类似的东西。

This is bizarre. I can only conclude that this has something to do with ASP and OWIN thinking they are in different domains or something like that.

更新3 - 两者之间的奇怪行为

Update 3 - Strange behaviour between the two.

其他奇怪的行为认定 - Owin和ASP会话的超时时间是不同的。我所看到的是,我Owin会议是住不是通过某种机制我的ASP会活得更长。所以在登录时:
1)我有一个基础的Cookie会话权威性
2)我设置一些会话变量

Additional strange behaviour identified - Timeout of Owin and ASP session is different. What i am seeing is that my Owin sessions are staying alive longer than my ASP sessions through some mechanism. So when logging in:1.) I have a cookied based auth session2.) I set a few session variables

我的会话变量(2)owin cookie的会话变量力量重新登录,这将导致在我整个应用程序的意外行为前的死。 (人已经登录,但并没有真正登录)

My session variables(2) "die" before the owin cookie session variable forces re-login, which causes unexpected behaviour throughout my entire application. (Person is logged in but is not really logged in)

更新3B -

一些挖后,我看到了一个页面上说的形式验证超时和会话超时需要匹配一些意见。我想通常两者保持同步,但无论什么原因,两者不同步。

After some digging i saw some comments on a page that say the "forms" authentication timeout and session timeout need to match. I am thinking normally the two are in synch but for whatever reason the two are not in synch.

变通的摘要

1)始终验证之前,先创建一个会话。当你启动应用程序会话[解决办法] = 0基本上创建会话;

1) Always create a Session first before authentication. Basically create session when you start the application Session["Workaround"] = 0;

2)[实验]如果你坚持饼干确保您OWIN超时/长度比你sessionTimeout长在你的web.config(测试)

2) [Experimental] if you persist cookies make sure your OWIN timeout / length is longer than your sessionTimeout in your web.config (in testing)

推荐答案

我也遇到同样的问题,跟踪的事业OWIN ASP.NET主机实现。我会说这是一个错误。

I have encountered the same problem and traced the cause to OWIN ASP.NET hosting implementation. I would say it's a bug.

一些背景

我的发现是基于对这些集版本:

My findings are based on these assembly versions:


  • Microsoft.Owin,版本= 2.0.2.0,文化=中性公钥= 31bf3856ad364e35

  • Microsoft.Owin.Host.SystemWeb,版本= 2.0.2.0,文化=中性公钥= 31bf3856ad364e35

  • System.Web程序,版本= 4.0.0.0,文化=中性公钥= b03f5f7f11d50a3a

OWIN使用它自己的抽象与响应cookie的工作(的 Microsoft.Owin.ResponseCookieCollection 的)。此实现直接包装响应头采集并相应更新的设置Cookie 的头。 OWIN ASP.NET主机( Microsoft.Owin.Host.SystemWeb 的)只是包装的 System.Web.Htt presponse 的,它的头集合。所以,当通过OWIN创建新的cookie,响应的的Set-Cookie 的头直接更改。

OWIN uses it's own abstraction to work with response Cookies (Microsoft.Owin.ResponseCookieCollection). This implementation directly wraps response headers collection and accordingly updates Set-Cookie header. OWIN ASP.NET host (Microsoft.Owin.Host.SystemWeb) just wraps System.Web.HttpResponse and it's headers collection. So when new cookie is created through OWIN, response Set-Cookie header is changed directly.

但ASP.NET还使用了它自己的抽象与响应cookie工作。这暴露我们作为的 System.Web.Htt presponse.Cookies 的财产和密封类的 System.Web.HttpCookieCollection 的实施。此实现不换行响应的设置Cookie 的头部直接,但使用一些优化和内部通知的少数体现它改变了状态,以响应对象。

But ASP.NET also uses it's own abstraction to work with response Cookies. This is exposed to us as System.Web.HttpResponse.Cookies property and implemented by sealed class System.Web.HttpCookieCollection. This implementation does not wrap response Set-Cookie header directly but uses some optimizations and handful of internal notifications to manifest it's changed state to response object.

再有就是在请求生命周期的一个点,其中后期的 HttpCookieCollection 的状态发生了改变测试( System.Web.Htt presponse.GenerateResponseHeadersForCookies()的)和饼干序列化的设置Cookie 的头。如果该集合是在一些特定的状态,整体的Set-Cookie头先清除并重新创建从存储在采集区。

Then there is a point late in request lifetime where HttpCookieCollection changed state is tested (System.Web.HttpResponse.GenerateResponseHeadersForCookies()) and cookies are serialized to Set-Cookie header. If this collection is in some specific state, whole Set-Cookie header is first cleared and recreated from cookies stored in collection.

ASP.NET会话实现使用的 System.Web.Htt presponse.Cookies 的属性来存储它的ASP.NET_SessionId的cookie。也有在ASP.NET会话状态模块的一些基本的优化( System.Web.SessionState.SessionStateModule 的)通过名为s_sessionEverSet静态属性这是相当自我解释执行。如果你的东西存储会话状态在应用程序中,该模块会做多一点的工作,为每个请求。

ASP.NET session implementation uses System.Web.HttpResponse.Cookies property to store it's ASP.NET_SessionId cookie. Also there is some basic optimization in ASP.NET session state module (System.Web.SessionState.SessionStateModule) implemented through static property named s_sessionEverSet which is quite self explanatory. If you ever store something to session state in your application, this module will do a little more work for each request.

返回我们的登录问题

使用这些作品的情况下可以解释。

With all these pieces your scenarios can be explained.

案例1 - 会话从未设置过

System.Web.SessionState.SessionStateModule 的,s_sessionEverSet属性为false。无会话ID的由会话状态模块产生的 System.Web.Htt presponse.Cookies 的收集状态的更改为未检出。在这种情况下,OWIN cookie被正确地发送到浏览器和登录作品

System.Web.SessionState.SessionStateModule, s_sessionEverSet property is false. No session id's are generated by session state module and System.Web.HttpResponse.Cookies collection state is not detected as changed. In this case OWIN cookies are sent correctly to the browser and login works.

案例2 - 会话某处使用应用程序,而不是之前的用户尝试认证

System.Web.SessionState.SessionStateModule 的,s_sessionEverSet属性为true。会话ID是通过的 SessionStateModule 的产生,ASP.NET_SessionId被添加到的 System.Web.Htt presponse.Cookies 的集合,但它在请求生命周期后移除用户的会话其实空。在这种情况下的 System.Web.Htt presponse.Cookies 的收集状态的检测为改变设置Cookie 的头前先清除Cookie被序列化到标头值。

System.Web.SessionState.SessionStateModule, s_sessionEverSet property is true. Session Id's are generated by SessionStateModule, ASP.NET_SessionId is added to System.Web.HttpResponse.Cookies collection but it's removed later in request lifetime as user's session is in fact empty. In this case System.Web.HttpResponse.Cookies collection state is detected as changed and Set-Cookie header is first cleared before cookies are serialized to header value.

在这种情况下,OWIN响应Cookie被丢失和用户没有通过验证,并重定向回登录页。

In this case OWIN response cookies are "lost" and user is not authenticated and is redirected back to login page.

案例3 - 会话的用户之前使用尝试认证

System.Web.SessionState.SessionStateModule 的,s_sessionEverSet属性为true。会话ID是通过的 SessionStateModule 的,ASP.NET_SessionId被添加到的 System.Web.Htt presponse.Cookies 的产生。由于内部优化的 System.Web.HttpCookieCollection 的和的 System.Web.Htt presponse.GenerateResponseHeadersForCookies()设置 - Cookie头是不是先清除,但只有更新。

System.Web.SessionState.SessionStateModule, s_sessionEverSet property is true. Session Id's are generated by SessionStateModule, ASP.NET_SessionId is added to System.Web.HttpResponse.Cookies. Due to internal optimization in System.Web.HttpCookieCollection and System.Web.HttpResponse.GenerateResponseHeadersForCookies() Set-Cookie header is NOT first cleared but only updated.

在此情况下,两个OWIN身份验证Cookie和饼干ASP.NET_SessionId响应和登录作品被发送。

In this case both OWIN authentication cookies and ASP.NET_SessionId cookie are sent in response and login works.

与饼干更一般的问题

正如你所看到的问题是更普遍的,而不是仅限于ASP.NET会话。如果您是通过托管OWIN的 Microsoft.Owin.Host.SystemWeb 的你/的东西是直接使用的 System.Web.Htt presponse.Cookies 的收集您将面临风险

As you can see the problem is more general and not limited to ASP.NET session. If you are hosting OWIN through Microsoft.Owin.Host.SystemWeb and you/something is directly using System.Web.HttpResponse.Cookies collection you are at risk.

例如这部作品和饼干都正确发送到浏览器...

For example this works and both cookies are correctly sent to browser...

public ActionResult Index()
{
    HttpContext.GetOwinContext()
        .Response.Cookies.Append("OwinCookie", "SomeValue");
    HttpContext.Response.Cookies["ASPCookie"].Value = "SomeValue";

    return View();
}

这并不并OwinCookie丢失...

But this does not and OwinCookie is "lost"...

public ActionResult Index()
{
    HttpContext.GetOwinContext()
        .Response.Cookies.Append("OwinCookie", "SomeValue");
    HttpContext.Response.Cookies["ASPCookie"].Value = "SomeValue";
    HttpContext.Response.Cookies.Remove("ASPCookie");

    return View();
}

无论从VS2013,IISEx preSS测试,默认MVC项目模板。

Both tested from VS2013, IISExpress and default MVC project template.

这篇关于ASP.NET_SessionId + OWIN Cookie不会发送到浏览器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 10:12