Increase timeout of an already started session - c#

I want to add a "keep me logged in" option to my custom login control.
This is how I'm currently using the session:
I'm saving and reading values from HttpContext.Current.Session["key"] manually. Works fine.
Relevant parts of web.config:
<sessionState mode="StateServer" useHostingIdentity="true" cookieless="false" timeout="120" stateConnectionString="tcpip=127.0.0.1:42424" />
<authentication mode="Forms">
<forms loginUrl="/login" name="AuthCookie" timeout="120" slidingExpiration="true" path="/" />
</authentication>
<authorization>
<allow users="*" />
</authorization>
As you can see, the default duration of a session is 120 minutes.
"Logout":
Session.Clear();
Session.Abandon();
Through a custom login control with textboxes, I grant access to a member area. (I don't use System.Web.Security.FormsAuthentication)
After entering valid credentials and a checked checkbox "keep logged in", I want to increase the duration of the already active session to ~30 days.
So far I've found solutions like
FormsAuthenticationTicket fat = new FormsAuthenticationTicket(1, "username", DateTime.Now, DateTime.Now.AddMinutes(1), false, "username");
string encTicket = FormsAuthentication.Encrypt(fat);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket) { Expires = fat.Expiration });
which don't work, because System.Web.Security.FormsAuthentication.Timeout is still at 120 minutes.
The same goes for setting
Session.Timeout = 666;
Any suggestions?

You can't really approach it this way. You can't persist a session over days - it's just not going to scale well.
What most people do is provide a means for automatic login, so that when their session expires, they are seamlessly logged back in on the next action/reload. Most people do this with a cookie that contains a unique hash, which is checked at the server. If you want the person to be logged in for 30 days, you just set the cookie to expire in 30 days time.

I decided to give a short summary how I ended up doing it, because #David Haney asked me to:
I added a column to my usertable, which contains a GUID that is used for "relogging in" / giving credentials again. That GUID is created upon login and stored in the database.
It's also stored as an ecrypted value in a cookie. (My site doesn't use SSL)
Added to Login routine (if a user checked the "remeber me" checkbox):
HttpCookie aCookie = new HttpCookie("Session");
Guid sessionGuid = // Buisiness layer call to generate value
String sessionID = sessionGuid.ToString();
aCookie.Value = Helper.Protect(sessionID, "sessionID");
aCookie.Expires = DateTime.Now.AddDays(30);
Response.Cookies.Add(aCookie);
where Helper.Protect and Helper.Unprotect are used from here How to use MachineKey.Protect for a cookie? to store an encrypted and MAC signed value in a cookie.
Relogging is done by having every content page inherit from a class, that implements that logic and inherits from System.Web.UI.Page.
public class BasePage : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (Request.Cookies["Session"] != null && !CustomIsLoggedInCheckMethod)
{
String unprotected = Helper.Unprotect(Request.Cookies["Session"].Value, "sessionID");
Guid sessionID = Guid.Parse(unprotected);
// Calls to buisiness layer to get the user, set sessions values et cetera
}
}
}
If a user was banned after the last session or logs out, the cookie value expiration date will be set to a date in the past:
HttpCookie myCookie = new HttpCookie("Session");
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
Edit:
Ah I forgot to mention this. I've also added a notification bar, that tells the user that he has been logged back in. It's based on http://blog.grio.com/2012/11/a-copypaste-ble-jquery-notification-bar.html
See Demo

Related

How setting session expired time use code on ASP.NET MVC5?

I'm not use FormsAuthenticatio.
When the user Login, I will save the user info to on session like:
HttpContext.Current.Session["UserId"] = model.Id;
HttpContext.Current.Session["Name"] = model.Name
But How I set the session expired time use code?
Maybe only for 30 minute, Maybe User select "Remember Me" then save it 24 hour.
Second question is : If I'm already set it expired time on web.config like:
<sessionState mode="InProc" timeout="30" />
Then How about the priority ? config first or code first?
You can set session in code, global.asax on session_start event using this.
Session.Timeout = 24*60 ;
I have checked in code that, setting session in code like above override that in web.config. So the above has more priority and this will be used and web.config's value will be discarded.
if the user ticks "Remember Me", just add a random guid to a database of active users and give them a cookie with the same guid. when the user comes back without a valid session, check for the cookie and search the database for the guid. if valid, the user is signed in

Asp.net persistent login cookie expires randomly

I'm trying to implement a login form with the remember me functionality in ASP.NET 4.0.
I've set the timeout option in the web.config to 1 year (525600), but after a random amount of time after I logon, I always get logged off.
The cookie is created correctly, I can see it in the browser with the right expire value (september 2014), but it seems that this cookie after some time is not readed by the ASP.NET environment anymore.
I tryed to login with:
FormsAuthentication.RedirectFromLoginPage(username, true);
or:
FormsAuthentication.SetAuthCookie(username, true);
Response.Redirect("/");
or with this custom code:
DateTime expiryDate = DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, userid, DateTime.Now, expiryDate, true, String.Empty);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
authenticationCookie.Expires = ticket.Expiration;
Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
Response.Cookies.Add(authenticationCookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(username, false));
But the result is always the same. The cookie is present, but after some time it's not used anymore.
The Web.config is like so:
<authentication mode="Forms">
<forms loginUrl="/login" defaultUrl="/" name="appName" path="/" timeout="525600" slidingExpiration="true"/>
</authentication>
The odd thing is that in my local test environment (ASP.NET Development server) things works correctly. Only in the production environment it is not working!
#Felipe Garcia: I don't know if I'm using a load balancer, I'm on a public server. But I tryed to config the MachineKey as you said (using the generator here) and now it seems to work correctly!
Thank you!

Session time out very short in hosting environment? Test for the loss of sessions?

My sessions timeouts are very short on my hosting environment, some times even 2 seconds and they timeout.
The sessions are reset if the user continues to use the website, unless the session = null and the count is 0.
The sessions should time out after 20min and then redirect the user to the log in page
The code for this is below:
protected override void OnInit(EventArgs e)
{
if (this.Session != null && this.Session.Count > 0)
{
string email = (string)this.Session["Email"];
int practiceId = (int)this.Session["PracticeId"];
int practitionerId = (int)this.Session["PractitionerId"];
this.ClientScript.RegisterHiddenField("loggedInUserName", email);
this.ClientScript.RegisterHiddenField("practiceId", practiceId.ToString());
this.ClientScript.RegisterHiddenField("practitionerId", practitionerId.ToString());
}
else
{
this.Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
Response.Redirect("~/Default.aspx");
}
base.OnInit(e);
}
Does anyone know why my session timeout could be so short?
When using my site sometime i can move around for 2-5 minutes with no timeout and other time 10s in i get a time out. What could cause session being lost, are they any ways to avoid or test for the loss of sessions?
Thanks in advance.
I assume you are overriding the init function for the page, but potentially abandoning the session on every page load could cause more issues than it solves. I would check for the existence of the session inside the master page:
protected void Page_Init(object sender, EventArgs e)
{
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
// user is not logged in
string ReturnUrl = HttpContext.Current.Request.Url.PathAndQuery;
string RedirectUrl = "/Login.aspx";
if (!String.IsNullOrEmpty(ReturnUrl))
{
RedirectUrl += "?ReturnUrl=" + Server.UrlEncode(ReturnUrl);
}
Response.Redirect(RedirectUrl);
}
}
If this is in the master page it will check on each request (made to an aspx page that inherits from the master) that will redirect the user to the login page.
If your app is sharing an application pool, you might be sharing the cookie id with another application:
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" timeout="60" name="MY_COOOKIE_NAME" slidingExpiration="true" />
</authentication>
<sessionState timeout="60" />
The MY COOKIE NAME will identify the cookies your app uses, other apps might have the default cookie name, so your sessions although apparently authenticated don't belongto the app as they are getting overwritten by a different app. The sliding expiration means that your session time will be extended everytime you visit a page.
Also, check that the machineKey config element is present, this made my sessions more stable:
<machineKey
validationKey="random_validation_key"
decryptionKey="random_decryption_key"
validation="SHA1" decryption="AES" />

How can I expire the session when the user doesn't work with website?

Hello, I created a web site application with asp.net 4.5 and asp.net membership. I want user session to be expire if the user doesn't work with site (like Facebook).
I have set the timeout in web.config for the session but this time gets finished (times out), either if user works or doesn't work. Is there something I'm missing?
<authentication mode="Forms">
<forms loginUrl="~/Pages/Login.aspx" slidingExpiration="true" timeout="1"></forms>
</authentication>
While setting the forms auth cookie you need to set an expiry time for the cookie and create a http module in your application where you check the auth cookie in the request headers and if its not present you logout the user and redirect to the login page. And if the cookie exists just reset the expiry time for the cookie in the response.
Refer to this link. This is an answered that I'm currently help with another user. This should show you how to make the session start once the user logs in.
Edit: Not sure why the downvote, but here is code then.
Change the timeouts on each of the forms authentication and sessionState like below.
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" defaultUrl="~/Dashboard.aspx" timeout="60"/>
</authentication>
<sessionState timeout="60" mode="InProc" cookieless="false" />
Then, put this into your Site.Master.cs under the page load.
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
// Handle the session timeout
string sessionExpiredUrl = Request.Url.GetLeftPart(UriPartial.Authority) + "/DealLog/Account/SessionExpired.aspx";
StringBuilder script = new StringBuilder();
script.Append("function expireSession(){ \n");
script.Append(string.Format(" window.location = '{0}';\n", sessionExpiredUrl));
script.Append("} \n");
script.Append(string.Format("setTimeout('expireSession()', {0}); \n", this.Session.Timeout * 60000)); // Convert minutes to milliseconds
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "expirescript", script.ToString(), true);
}
The session will only expire if the user is authenticated. The user logs in, becomes inactive, and then session times out. Once it times out, goes to an SessionExpired page. On the session expired page, place
FormsAuthentication.SignOut();
in the page load so it signs out the user. Then you can set up a redirect from there. The Authentication and SessionState timeouts are both in minutes. 60 = 1 hour.
Edit 2: It looks like the user of the question that was linked in my answer was deleted by the user. Sorry for that. Hope this helps though.

User not logged in when WWW. is on URL

If I visit my site with out the www. prefix, login and then add the www., my user is not logged in any more, but if I remove the www., the user is logged in. It acts the same way if I do the Opposite. go to the web site with the www., login, and then remove the www. the user will not be logged in.
Here is the Login method and the authentication at the web.config.
public static void LogIn(userId)
{
Item user = Framework.Business.Item.Load(userId);
var _ticket = new FormsAuthenticationTicket(1, _usrItm.ID, DateTime.Now, DateTime.Now.AddDays(30), true, _usrItm.ID);
string encTicket = FormsAuthentication.Encrypt(_ticket);
HttpContext.Current.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
}
<authentication mode="Forms">
<forms name="k_Authentication" protection="All" timeout="120" cookieless="UseCookies" loginUrl="default.aspx" path="/" defaultUrl="/myweb.aspx"/>
</authentication>
I'll bet you a shilling to a guinea that the two answers about the domain setting of the cookies are correct +1s all around from me.
However. Most often the two sites are the same or they are not. If they're not, then you usually want the user to no longer be logged in, so don't change anything. If they are the same, then set one to permanently redirect to the other. As well as making this problem go away, you also gain some SEO benefits, benefits for people's history records being more consistent, and reduced pressure on shared caches. So I'd suggest that approach. I'd only deal with the matter of the domain set on the cookie if the two are separate-but-related, and sharing the log-in between them is appropriate.
There is probably a problem with the domain of your cookie. www.example.com and example.com are not the same domain.
You'll have to set the Domain property to www.yourdomain.com manually to share the cookies.

Categories