I'm using FormsAuthentication, I'm having problems setting the TimeOut value.
I've seen some other posts related to this, but they don't seem to be exactly my problem or the solution suggested doesn't help.
My web.config has the following:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn"
timeout="1"
cookieless="UseCookies" />
</authentication>
I have put an AuthorizeAttribute on the controllers that I want to secure.
I can view the .ASPXAUTH cookie (using FireCookies) and I can see that it is set to expire in 1 minute after a login.
If I debug through my code I can see that FormsAuthentication.Timeout = 1.
However my ticket doesn't seem to timeout in 1 minute. After 1 minute of inactivity I can still browse to controllers with AuthorizeAttribute.
In fact I can actually delete the .ASPXAUTH cookie using FireCookies and I can still browse to controllers with an AuthorizeAttribute.
Bizarrely after being inactive for a long time (sorry don't have an exact time - I was out for lunch!) the TimeOut occurs and I am redirected
to the login screen.
Any ideas?
I too had the same problem. Actually, it came about because I could not read the forms authentication cookie from javascript, it was after a while undefined
. I just wanted to know if I was authenticated via javascript.
Later I found that the ticket had expired, but I was not getting logged out (also. so i wanted to solve that too)! I saw your question had not been answered so I kept it open while I worked out my problems for half a day. The following is what I came up with that appears to be working.
My Answer is based on this answer. https://stackoverflow.com/a/454639/511438 by user ScottS
This is in my ASP.NET MVC 3 project.
Here is my login code. Not shown, the custom user authentication logic before it. This just sets the initial ticket.
public class FormsAuthenticationService : IFormsAuthentication
public void SignIn(string userName, bool createPersistentCookie, string role)
{
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
1, // version
userName, // user name
DateTime.Now, // created
DateTime.Now.Add(FormsAuthentication.Timeout), // expires
false, // rememberMe?
role // can be used to store roles
);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
HttpContext.Current.Response.Cookies.Add(authCookie);
}
in the same class but a static method that is accessed from global.asax
//-- this is based on https://stackoverflow.com/questions/454616/asp-net-cookies-authentication-and-session-timeouts
internal static FormsAuthenticationTicket RefreshLoginCookie(bool retainCurrentExpiry)
{
HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null || authCookie.Value == null)
return null;
FormsAuthenticationTicket oldTicket = FormsAuthentication.Decrypt(authCookie.Value);
DateTime expiryDate = (retainCurrentExpiry ? oldTicket.Expiration : DateTime.Now.Add(FormsAuthentication.Timeout));
HttpContext.Current.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
var newTicket = new FormsAuthenticationTicket(oldTicket.Version, oldTicket.Name, oldTicket.IssueDate, expiryDate,
oldTicket.IsPersistent, oldTicket.UserData, oldTicket.CookiePath);
HttpCookie newAuthCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(newTicket));
HttpContext.Current.Response.Cookies.Add(newAuthCookie);
return newTicket;
}
Global.asax
My customization comes that ajax requests do not refresh the forms authentication ticket. So if you sit there for the timeout period, an ajax request will log you out. Change that if you want ajax requests to keep the ticket alive (addresses my javascript cookie issue, not your logout inactivity issue).
*(tip, if you get logged out, then login, but come back to the login page again, the first login did not specify a returnUrl in the querystring perhaps). *
protected virtual void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null || authCookie.Value == "")
{
return;
}
bool isAjax = new HttpRequestWrapper(System.Web.HttpContext.Current.Request).IsAjaxRequest();
FormsAuthenticationTicket authTicket;
try
{
//-- THIS IS WHAT YOU WANT
authTicket = FormsAuthenticationService.RefreshLoginCookie(isAjax);
}
catch
{
return;
}
string[] roles = authTicket.UserData.Split(';');
if (Context.User != null) Context.User = new GenericPrincipal(Context.User.Identity, roles);
}
Web.config
here is the part where i set session timeout and ticket timeout
<configuration>
<system.web>
<sessionState mode="InProc" timeout="60" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="60" name="ProviderMvcSession" cookieless="UseCookies" />
</authentication>
It's about how long is the timeout of your session. Default is 20 minutes and you can change it in web.config like this:
<sessionState mode="InProc" timeout="20"/>
An obvious solution that could easily be looked over by some people, clearing the browser cookies or logging out should solve the issue. If remember me is checked, the application will keep logging in with the old cookie regardless the changes made to the Web.Config timeout value.