Forms Authentication and Persistant Login Problems
I'm mucking around with an authentication form that requires some extra authentication data for the user, so rather than using the stock Login control and it's authenticate method I'm using a custom ticket and manually redirecting the data. I'm not sure how this option to stick custom user data into the ticket escaped me until today, but somehow I missed it over the years <s>. This is obviously quite useful in scenarios where you just need one or two small pieces of user information that you'd otherwise have to store in Session or in an associated user table/membership all of which involves some additional overhead. In two busy applications I'm running this will definitely come in hand and remove the need to run sessions altogether. Duh (sound of hand slapping on forehead <g>).
[updated from Comments - 9/23]
Anyway, here's the code I'm using to handle the Login click from the this manual entry form (ie. no Login Control):
protected void LoginButton_Click(object sender, EventArgs e)
{string username = this.Username.Text;
string password = this.Password.Text;
bool remember = this.RememberMe.Checked;
if (UserObject.AuthenticateAndLoad(username,password) != null)
{FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
username, DateTime.Now, DateTime.Now.AddDays(10),
remember, UserObject.Entity.UserName);
string ticketString = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, ticketString);
if (remember) cookie.Expires = DateTime.Now.AddDays(10);Response.Cookies.Add(cookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(username, false));
// *** This works too, although it sends the full page content in addition to Redirect header???
// FormsAuthentication.RedirectFromLoginPage(username,remember);}
else {this.ErrorDisplay.ShowError("Invalid Login. Please make sure you fill in username and password.");
}
}
The authentication seems to work just fine as I get logged into my application, but for some odd reason the cookie is not created as a persistent cookie when the form is submitted. Just for kicks I also created another form with a LoginControl on it and it too doesn't seem to respect the persistance flag when set on the RememberMe var (or the default control).
Well it turns out I skipped setting hte cookie expires code above which makes perfect sense.
The problem here is that it's confusing of where the expiration is exactly applied. Both the ticket and the GetRedirectUrl() contain the expiration information, and so I assumed that ASP.NET was automatically injecting itself in the middle to set the expiration on the cookie explicitly. Not so - even if you use the explicit RedirectFromLoginPage() - if you call that method directly with the persistCookie option to true, ASP.NET will generate a generic (read very long) expiration time.
In short with the explicit ticket you need to be - well, explicit with the cookie and redirect and handle it all yourself. On future accesses ASP.NET might reissue the ticket and THEN it uses the information provided in the original ticket, but only then not on the original request.
Incidentally I ended up here because I also had problems with the plain old Login control not creating a persistent cookie EVEN IF the Remember me checkbox was applied.
This would not work until explicitly adding the slidingExpiration key:
<authentication mode="Forms"> <forms timeout="44000" slidingExpiration="true" ></forms> </authentication>
Thanks to Bilal who pointed at the link in the comments below that pointed at the solution.
Other Posts you might also like
- Adding minimal OWIN Identity Authentication to an Existing ASP.NET MVC Application
- Resolving Paths To Server Relative Paths in .NET Code
- Map Physical Paths with an HttpContext.MapPath() Extension Method in ASP.NET
- Getting the ASP.NET Core Server Hosting Urls at Startup and in Requests
- Back to Basics: Rewriting a URL in ASP.NET Core
The Voices of Reason
# re: Forms Authentication and Persistant Login Problems
Check this blog post:
http://geekswithblogs.net/vivek/archive/2006/10/13/93956.aspx
I am sure it will solve your problem!
Regards
# re: Forms Authentication and Persistant Login Problems
@Bilal thanks for the link - yes adding the slidingExpiration made the LoginControl work also.
I've updated the post above to reflect both of these comments. Thanks!
# re: Forms Authentication and Persistant Login Problems
"This would not work until explicitly adding the slidingExpiration key"
slidingExpiration if not specified, is true. therefore it was already set to true in your case.
# re: Forms Authentication and Persistant Login Problems
I think your problem is that you aren't setting an expires date/time on the cookie.
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,ticketString); cookie.Expires = DateTime.Now.AddDays(10); Request.Cookies.Add(cookie);Sure would have been nice if they offered a constructor overload with an expires parameter...