Cookie expires or session timeout too soon - asp.net-mvc

I have code like this which is run when a user is authorized:
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
1,
email,
DateTime.Now,
DateTime.Now.AddMinutes(120),
true,
userData);
string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
faCookie.Expires = authTicket.Expiration;
Response.Cookies.Add(faCookie);
I then redirect to a controller/Action that has the Authrize attribute:
[Authorize]
public class ProductsController : Controller
{
I have the following in web.config:
<authentication mode="Forms">
<forms loginUrl="~/Home/Unauthorized" timeout="2880" />
</authentication>
<sessionState timeout="120"></sessionState>
However users are complaining of session timing out or redirecting Home/Unauthorized after a couple of mins of inactivity.
what could be causing this, what else should i check?

A couple of thoughts before I go into a possible solution of why your logins are expiring. First, the FormsAuthentication cookie and SessionState are two different things completely. You can have one or the other, or both or neither. As a result, the timeouts for these two items are also not related.
The FormsAuthentication cookie is an encrypted cookie that contains some basic information such as the user name and an expiration value. The .NET application uses this cookie once a user has authenticated to know if the user is authorized for certain resources.
What controls the encryption and decryption of the FormsAuthentication cookie is the MachineKey for that web application on IIS. The MachineKey is a set of keys used to encrypt and decrypt the cookie. By default, a web application on IIS is set to AutoGenerate the machine key. What this means is that when an application starts, a random machine key is generated. If an application recycles, you get a new machine key. Additionally, if you are hosting on a shared provider, the web host will typically have your application load balanced, meaning hosted by more than one server. Each one of those servers will auto generate a machine key.
If your web application is on a load balanced scenario, then each machine in the web farm cannot decrypt the other's encrypted cookie. This will give the appearance of "being logged out". The example of this is logging in on web server A, then a subsequent request goes to web server B. Web server B does not share a machine key with web server A and cannot decrypt the cookie, sending the user back to the login page.
The solution is to define the MachineKey section in your web.config so each instance of IIS will use the same keys as well as if the application pool recycles, you still have the same machine key.
Here would be an example machine key (use the .NET 2.0 version) that you could place in your web.config
<system.web>
<machineKey validationKey="EBC1EF196CAC273717C9C96D69D8EF314793FCE2DBB98B261D0C7677C8C7760A3483DDE3B631BC42F7B98B4B13EFB17B97A122056862A92B4E7581F15F4B3551"
decryptionKey="5740E6E6A968C76C82BB465275E8C6C9CE08E698CE59A60B0BEB2AA2DA1B9AB3"
validation="SHA1" decryption="AES" />
</system.web>
Additional thoughts are that your expiration in your web.config (2880) and what you are actually setting the expiration to be (120) do not match. You may want them both to match.

If you are running behind a load balancer you will want to ensure that the web farm is using a consistent key as pointed out by Tommy's answer.
Other things to check will be that the IIS metabase settngs for each server are identical. They need to have the same path and ID.
You will also want to look at holding session out of proc (your web.config looks like in proc) which is susceptible to network outage and random app recycles.
Basically a summary of this link.
http://msdn.microsoft.com/en-us/library/vstudio/ms178586(v=vs.100).aspx
If you can post more of your config if possible and give more detail about your environment setup it will be easier to point you in a more focused direction.

Try This one:
web.config Code:
<system.web>
<httpRuntime maxRequestLength="40000000" useFullyQualifiedRedirectUrl="true" executionTimeout="600000" />
<authentication mode="Forms">
<forms loginUrl="~/Home/Unauthorized" timeout="2880" cookieless="UseCookies" />
</authentication>
</system.web>
This will help you.

Related

After adding the SessionState tag in web.config file, URL gets changed.

I am developing MVC application.
I have added the below code in web.config to handle session.
<system.web>
<sessionState mode="InProc" cookieless="true" timeout="30" />
</system.web>
after adding this code , when I run the application , I get the following url in browser.
http://localhost:65344/(S(egpaesodxcoii0dxtczyi10c))/Login/LoginUser
I am confused about (S(egpaesodxcoii0dxtczyi10c)) this part.
if I remove this SessionState tag
<sessionState mode="InProc" cookieless="true" timeout="30" />
from web config then it start appearing normal like below
http://localhost:65344/Login/LoginUser
whats the issue ?
There is no issue.
When you use Cookieless sessionstates, the user's sessionId is embedded in the url. If you do not want this embedded you should consider setting Cookieless to false.
I recommend you have a read of this documentation it should outline the differences between the two.
Hope you find this useful.
There are two ways that session state can store the unique ID that associates the client with a server session: by storing an HTTP cookie on the client or by encoding the session ID in the URL. Storing the session ID in the cookie is more secure but requires the client browser to support cookies.
For applications that allow clients that do not support cookies, such as a variety of mobile devices, the session ID may be stored in the URL. The URL option has several drawbacks. It requires that the links on the site be relative and that the page be redirected at the beginning of the session with new query-string values, and it exposes the session ID right in the query string, where it can be picked up for use in a security attack.
You are encouraged to use the cookieless mode only if you need to support clients that lack cookie support.
So setting : cookieLess to False will work for you
<system.web>
<sessionState mode="InProc" cookieless="false" timeout="30" />
</system.web>

How to add to Azure Session Cookies HttpOnly and Secure attributes

In my ASP.NET MVC 4 application I use a third-party service. And one of the service's terms of use is adding to all session cookies HttpOnly and Secure attributes.
WebSite hosted on Windows Azure and works on SSL.
I added to root web.config the following settings:
<httpCookies httpOnlyCookies="true" requireSSL="true" lockItem="true"/>
<authentication mode="Forms">
<forms loginUrl="~" timeout="2880" requireSSL="true" />
</authentication>
So now my application session cookie ".ASPXAUTH" has HttpOnly and Secure attributes.
But the main problem that Azure Balancer "WAWebSiteSID" and "ARRAffinity" cookies don't have this attributes.
Could you help me to find appropriate solution to add missing attributes to them?
I don't believe you can modify the secure and HttpOnly attributes as the cookies are added to the response downstream of the app (i.e. by a load balancing appliance that sits in front of the site).
Of course the pragmatic question is "why"? What advantage would you gain by not allowing client script or an MitM on the wire to access these cookies? They're nothing more than bytes of data intended to tie clients to site instances and contain nothing of a personal nature nor provide any conceivable upside for an attacker (at least not that I can think of).
The answer is probably "because it keeps a security scanning tool happy" which may make you feel warm and fuzzy, but of course it doesn't actually change the practical security position of the site one iota.
As of June 24, 2017, this is changing and ARRAffinity cookies will be set with the HttpOnly flag in the future. https://github.com/Azure/app-service-announcements/issues/12

ASP.NET MVC membership - user being logged out frequently - don't know why

I have an ASP.NET MVC 4 web application. Running locally, it works fine, but on the web host (which uses shared hosting), the logged on user is frequently logged out by being redirected back to the home page. In most cases, the user is logged out after performing only a few actions.
The web host suggested that my application could be using up too much memory but I used a program to profile the memory usage and I confirmed that it wasn't using excessive amounts of memory - in fact the application seems to use a fraction of the allocated memory on the web host.
Here is the logon method that is used:
public static Boolean Login(string Username, string Password, bool persistCookie = false)
{
bool success = Membership.ValidateUser(Username, Password);
if (success)
{
FormsAuthentication.SetAuthCookie(Username, persistCookie);
}
return success;
}
In my web host, the forms authentication timeout is set to 60 minutes, so that shouldn't be an issue, right?
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="60" />
</authentication>
and my session state timeout value is also set to 60 minutes:
<sessionState mode="InProc" customProvider="DefaultSessionProvider" timeout="60">
Based on the answer here, I added this line also, which didn't seem to solve the issue:
<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps"></machineKey>
Any ideas to what the problem might be and what I can do to solve the problem?
Your sessions are not timing out. The IIS is crashing. Since you are using in memory sessions, every time IIS crashes, your sessions are gone and the user gets logged out. You should check the server's event views and look into details of errors to find out what the error is.
I set my timeout to 2880 in the authentication timeout for web.config and I also set the sessionState before closing system.web
<sessionState timeout="1440"></sessionState>
This will keep the session active for 24 hours.

ASP.NET MVC Application Timeout Not Working

In my Web.config file, I have been trying to set the session timeout. I used the following code:
<configuration>
<system.web>
<sessionState timeout="1"></sessionState>
</system.web>
</configuration>
When I ran the app, the timeout was still set to the default 20 minutes. Trying to figure out why the settings are not applying. Please help! Thanks!
Don't be confused between ASP.NET session timeout (which is what you set) and Forms Authentication cookie timeout which is something entirely different and controlled by the <forms> tag:
<authentication mode="Forms">
<forms
loginUrl="/login"
timeout="1" />
</authentication>
ASP.NET session uses cookies to track users (it has nothing to do with authentication) and associate their unique id with a hashtable stored on the server. Forms authentication on the other hand is a means of tracking authenticated users in ASP.NET. It uses cookies but it is a different cookie than the ASP.NET session.

Forms authentication & subdomain

I'm trying to use forms authentication that will work for both my top level domain & sub domains.
for example, if I log in with this domain: mydomain.com and afterwards going to www.mydomain.com i want to have the ability to identify the user who logged on to mydomain.com (it's the same application).
i'm using the following in my web.config file:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" domain="mydomain.com" timeout="2880" />
</authentication>
This is an mvc project, and i'm getting the user id with the following API:
HttpContext.Current.User.Identity.Name
The creation of form authentication cookie is done by the following api after performing openid logon to the user:
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
I can see that the authentication cookie is being sent to both domain but only the domain that the authentication was made against recognizes the user.
Am i doing something wrong?
Thanks,
Lior
Make sure you have the same machine keys setup for those two applications. If the authentication token is encrypted with the machine key of application 1 and application 2 has different key it won't be able to decrypt it.
This question isn't exactly the same as yours, but it looks like it's the solution your looking for.
You need to issue your ticket in the toplevel domain, in order to be recognized by subdomains. This is because of how cookies work:
If you set the cookie in domain.com it will be visible on sub.domain.com
However if you set it on sub.domain.com, it will not be visible on domain.com
This is a security issue because of cookies and you'll have to consider it, beyond the settings of the <form> element which have to do with validating/rejecting a authentication cookie, where you will need to have domain='domain.com', which you already do.
In addition to all this, if on the subdomain you have a different application, you will need to explicitly define the machine key to be the same. You can generate your self some keys here: http://aspnetresources.com/tools/machineKey

Resources