ASP.NET Authentication cookie
On an application that has form based authentication, I have a standard ASP.NET Login control with the following Authenticate event handler.
void Login_Authenticate(object sender, AuthenticateEventArgs e)
{
if (Security.AuthenticateUser(Login.UserName, Login.Password))
{
e.Authenticated = true;
RedirectFromLoginPage(Login.UserName);
}
else
{
e.Authenticated = false;
}
}
The RedirectFromLoginPage function goes like this :
private void RedirectFromLoginPage(String username)
{
String returnUrl = GetReturnUrl();
FormsAuthentication.SetAuthCookie(username, true, "/");
Response.Redirect(returnUrl, true);
}
This works fine in 99% of cases. However, I sometimes get support calls from people who can't log in. They will enter their credentials, get redirected back to the home page (which is what happens when everything works fine) but they won't be logged in.
Figuring it might be a cookie problem, I tried to reproduce the problem in my environment by setting my privacy options to "Block All Cookies" and I was able to reproduce the problem. The SetAuthCookie function is called, but on the next page load HttpContext.Current.User.Identity.IsAuthenticated
returns false.
In my web.config, the authentication is set like so :
<authentication mode="Forms">
<forms loginUrl="..." timeout="180" cookieless="AutoDetect"/>
</authentication>
Reading the documentation on MSDN about AutoDetect and SetAuthCookie, I got that :
AutoDetect Specifies that cookies are used, if the device profile supports cookies; otherwise, cookies are not used.For desktop browsers that are known to support cookies, a probing mechanism will be used to try to use cookies, when enabled. If a device does not support cookies, no probing mechanism will be used.
FormsAuthentication.SetAuthCookie : Creates an authentication ticket for the supplied user name and adds it to the cookies collection of the response, using the supplied cookie path, or using the URL if you are using cookieless authentication.
I would of thought that in my scenario, cookieless authentication would of been used but it isn't (I don't see anything in the QueryString after the redirect anyway).
If I set a b开发者_JAVA技巧reakpoint in the RedirectFromLoginPage function and test some values I get :
bool cookieSupport = Request.Browser.Cookies; //"true"
bool redirectWithCookies = Request.Browser.SupportsRedirectWithCookie; //"true"
HttpCookieMode currentMode = FormsAuthentication.CookieMode; //"AutoDetect"
I'm not sure if the Request.Browser.Cookies is meant to be true or not here. The browser does support cookies, but they are all blocked...
Anyway, I got to remote for a few minutes on a machine where the problem was happening. The privacy settings were set to medium so it should of been able to accept cookies. It was a standard Win7 / IE8 setup. I tried adding the website to the user's trusted zone, to login via https but it didn't work. Other problem setups were similar (nothing really stands out with the machines and the users tell me they have no problems on other websites)
So what am I doing wrong here?
Do you specify the domain for the forms authentication cookie in the web.config file? And does it match the domain for the website?
I believe Medium security settings in IE block third party cookies so the problem could be IE thinking your authentication cookie is a third party cookie.
A similar problem occured for me. But it was only for Internet Explorer 8. After some research, I figured that IE8 runs on cookiless mode by default. So, I changed this line in web.config:
<forms loginUrl="..." timeout="180" cookieless="AutoDetect"/>
to
<forms loginUrl="..." timeout="180" cookieless="UseUri"/>
, and it works fine.
精彩评论