浏览器在回发和重定向后偶尔会丢失用于身份验证的 HttpCookie

发布于 2024-10-09 08:03:05 字数 1914 浏览 2 评论 0原文

一段时间以来,这一直是一个棘手的问题,但非常零星且难以隔离。

有时,已在 Web 应用程序上进行身份验证、已打开一段时间、多次登录和退出同一 Web 应用程序、具有多个选项卡的浏览器几乎是任何浏览器(Chrome、IE、Firefox、 Safari),并且看似随机,在设置并随后进行重定向后失去了保留 AuthCookie 的能力。关闭浏览器并启动新会话可以解决该问题,打开另一个浏览器并尝试进行身份验证也可以解决该问题。

我们的团队对我们所有的网站和网络应用程序使用表单身份验证。这是一个非常典型的设置,其中显示登录表单,用户输入凭据并在回发的单击事件上设置 cookie,然后重定向到同一页面,然后引用 cookie 并用于完成身份验证。

在这种情况下

FormsAuthentication.FormsCookieName = ".WebAuth"

,在事件内:

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, Username, DateTime.Now, DateTime.Now.AddMinutes(SessionTimeout), false, Username);
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authTicket));
    Response.Cookies.Add(faCookie);
Response.Redirect(Request.RawUrl, true);

重定向后,在 PreInit 上:

HttpCookie authCookie = Request.Cookies[cookieName];

此时,authCookie 变量通常不为 null,但在我上面概述的这些孤立情况下,cookie 在重定向后返回 null。

这种情况的发生非常随机,有时会在影响我们的一位开发人员之前几周发生。正如我所说,重新启动浏览器可以解决该问题。

今天我在使用 Chrome 时在我们的开发服务器上发生了这种情况。我已登录该应用程序,允许应用程序会话超时,然后尝试再次登录。尝试登录后无法设置 cookie。我将 Visual Studio 远程连接到服务器上的进程以开始调试。在整个过程中,我可以单步执行我的代码,甚至可以通过更新将新的代码版本部署到服务器,重新启动应用程序,重新启动服务器上的 IIS,附加并重新附加到项目,但问题仍然存在于 Chrome 中。在 Firefox 中,我能够毫无问题地进行身份验证。

在 Chrome 中,登录将进行验证,并尝试设置如上所述的响应 Cookie。在重定向之前,我可以看到正确设置的响应 Cookie,以及请求 Cookie 中的对应内容。然而,在看似成功登录后的每次重定向中,响应和请求 Cookie 都消失了。

我在应用程序上启用了 Trace 以查看 cookie 集合:

Request Cookies Collection 中有一个 .WebAuth,以及 ASP.NET_SessionId 和几个 ASPSESSIONIDxxxxxxxx,但是当页面加载时,只有 ASP.NET_SessionId 和 ASPSESSIONIDxxxxxxxxx cookie 可用Request.Cookies 范围内,没有 .WebAuth 的标志。然而,在渲染后页面的Trace信息中,列出了多个.WebAuth cookies,只是页面似乎无法访问它们。

首先,在身份验证后的工作版本上,页面的跟踪信息中同时存在 .WebAuth 响应和请求 Cookie。但在无法正常工作的浏览器窗口上,响应 Cookie 不存在。

还有其他人有这方面的经验吗?这是一个令人烦恼的问题,而且是零星的,但我很希望能够解决它。我担心它可能会影响用户,而我们对此一无所知,因为问题的描述非常复杂。

This has been a nagging issue for some time, but very sporadic and difficult to isolate.

From time to time, browsers that have authenticated on a web application, have been open for a while, have logged in and out of the same web application multiple times, have multiple tabs, are pretty much any browser (Chrome, IE, Firefox, Safari), and seemingly at random, lose their ability to retain an AuthCookie after being set and followed by a redirect. Closing the browser and starting a new session resolves the issue, as does opening up a different browser and attempting to authenticate.

Our team uses forms authentication for all of our websites and web application. This is a pretty typical setup where a login form is displayed, the user enters credentials and a cookie is set on the click event of the postback, then a redirect occurs to the same page where the cookie is then referenced and used to complete authentication.

In this situation

FormsAuthentication.FormsCookieName = ".WebAuth"

Within Event:

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, Username, DateTime.Now, DateTime.Now.AddMinutes(SessionTimeout), false, Username);
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authTicket));
    Response.Cookies.Add(faCookie);
Response.Redirect(Request.RawUrl, true);

After the redirect, on PreInit:

HttpCookie authCookie = Request.Cookies[cookieName];

At this point, the authCookie variable is typically not null, but in these isolated circumstances that I've outlined above, the cookie comes back null after the redirect.

This happens very randomly, sometimes weeks before affecting one of our developers. As I said, restarting the browser resolves the issue.

Today I had it happen on our dev server while using Chrome. I had logged into the application, allowed the application to session timeout, and then attempted to login again. The attempted login then failed to set the cookie. I remotely attached Visual Studio to the process on the server to begin debugging. The entire time I could step through my code, even deploy new code versions to the server with updates, restart the app, restart IIS on the server, attach and reattach to the project, and the issue persisted in Chrome. In Firefox, I was able to authenticate without issue.

From Chrome, the login would validate, attempt to set a Response Cookie as outlined above. Prior to redirect, I could see the properly set Response Cookie, as well as its counterpart in the Request Cookies. However, on each redirect after a seemingly successful login, the Response and Request Cookie are gone.

I enabled Trace on the application to view the cookie collection:

There is a .WebAuth in the Request Cookies Collection, as well as ASP.NET_SessionId and several ASPSESSIONIDxxxxxxxx, but when the page loads, only the ASP.NET_SessionId and ASPSESSIONIDxxxxxxxx cookies are available in the Request.Cookies scope, no sign of the .WebAuth. However, in the page's Trace information after render, there multiple .WebAuth cookies listed, it is just that the page seems to have no access to them.

Primarily, on a working version after authentication there is both a .WebAuth Response and Request Cookie in the page's Trace info. But on a non functioning browser window, the Response Cookie is absent.

Has anyone else had any experience with this? It is such a nagging issue, and so sporadic, but I would love to be able to resolve it. My concern is that it may be affecting users and we would have no knowledge since the description of the issue is so convoluted.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

儭儭莪哋寶赑 2024-10-16 08:03:05

根据您的情况,您可能会遇到浏览器对每个域的 Cookie 数量/总数的限制。限制相对较高,但存在(规范:http://www.ietf.org/rfc/ rfc2109.txt,第 6.3 节,一些最新信息 - http://www.nczonline.net/blog/2008/05/17/browser-cookie-restrictions/

如果再次发生这种情况,请尝试查看实际的服务器响应(即使用 Fiddler)以查看如果cookies被发送到浏览器。检查为域和当前页面设置了哪些 cookie(根据浏览器的不同,有不同的方法,在所有浏览器中,您可以通过在地址栏中运行以下命令来查看一些 cookie javascript:alert(document.cookie))

Based on your scenario you may be running into browser's restrictions on number of cookies per domain/total. The limits are relatively high, but exist (spec: http://www.ietf.org/rfc/rfc2109.txt, section 6.3 , some recent information - http://www.nczonline.net/blog/2008/05/17/browser-cookie-restrictions/)

If you get it happening again try to look at actual server responses (i.e. using Fiddler) to see if cookies are send to the browser. Check what cookies are set for the domain and current page (depending on browser there are different ways of doing it, in all browsers you can see some cookies by running following in address bar javascript:alert(document.cookie) )

愛放△進行李 2024-10-16 08:03:05

这是一个非持久性 cookie 问题。会话只是超时。

尝试将这一行中的 false 更改为 true

FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, Username, DateTime.Now, DateTime.Now.AddMinutes(SessionTimeout), true, Username);

同时添加

faCookie.Expires = DateTime.Now.AddMinutes(SessionTimeout);

This is a non-persistent cookie issue. Session simply times out.

Try changing false to true in this line:

FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, Username, DateTime.Now, DateTime.Now.AddMinutes(SessionTimeout), true, Username);

Also add

faCookie.Expires = DateTime.Now.AddMinutes(SessionTimeout);
瀟灑尐姊 2024-10-16 08:03:05

我也遇到过类似的情况,事情正如你所描述的那样。但是,后来找到了原因。

ASP.NET 和 IIS 将 MyApplication 和 myapplication 视为相同的,但浏览器将它们视为不同的。因此,当我们为 /MyApplication 设置身份验证 cookie 时,当我们转到 /myapplication 时,它们不会发送到服务器。

接下来是修复:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        string url = HttpContext.Current.Request.Url.PathAndQuery;
        string application = HttpContext.Current.Request.ApplicationPath;

        if (!url.StartsWith(application))
        {
            HttpContext.Current.Response.Redirect(application + url.Substring(application.Length));
            Response.End();
            return;
        }
    }

I have fall in similar situation, things was certain as you described. But, later the reason have been found.

ASP.NET and IIS understood MyApplication and myapplication as one equal, but browsers undertood them as different. So, when we set auth cookies for /MyApplication, they were not sent to the server, when we go to /myapplication.

The fix is next:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        string url = HttpContext.Current.Request.Url.PathAndQuery;
        string application = HttpContext.Current.Request.ApplicationPath;

        if (!url.StartsWith(application))
        {
            HttpContext.Current.Response.Redirect(application + url.Substring(application.Length));
            Response.End();
            return;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文