Does ASP.NET Session state work without cookies? - asp.net

According to MSDN:
By default, the SessionID value is stored in a non-expiring session
cookie in the browser.
If I am trying to use Session State (I'm not using Cookieless Session IDs) and a users browser does not accept cookies, will Session State work?

According to this it is supported: http://msdn.microsoft.com/en-us/library/aa479314.aspx
<sessionState cookieless="true" />
The downside is that the session ID is placed in every URL used by the application:
http://yourserver/folder/(session ID here)/default.aspx
See this SO answer for additional details: Absolute URL Cookieless

Related

Session timeout is not working while using SqlServer mode

I am developing ASP.Net MVC application.
We have used sessionState mode SQLServer and i have set timeout to 20 minutes.
<sessionState mode="SQLServer"
sqlConnectionString="data source=127.0.0.1;user id=sa;password=sa"
cookieless="false"
timeout="2" />
Code is something like this in web config.
I have also set login page.
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
Now when session expires i want to navigate user to login page.
I checked many things but i was unable to understand how it exactly works? and how can i navigate user login page on session expire?
It is working in InProc mode. I used it in same way and user is redirected to login on session expire.
But i am unable to accomplish same thing in SQLServer Mode.
I am unable to understand what i am missing?
I checked Session State and also found that Session timeout handled in SQLServer Mode
Edit :-
I want to redirect user to login page whenever another http request is executed for that session.
Ordinarily the browser has no idea what is going on on the server. Unless an HTTP round trip occurs, it will remember the state of the session from when the page was rendered.
In addition, you session cookie is probably HttpOnly, so there is no way for the page to check for the presence of a session cookie.
One way to accomplish what you want is:
Add a hidden iFrame to your page. Set the SRC of the iFrame to a handler in your web site
The handler doesn't have to do much except return a 200 OK, plus a refresh header set to a few seconds, so that the handler gets continually polled.
context.Response.AddHeader("REFRESH", "2");
Add framebreaker code to your login page
if (top.location != location) {
top.location.href = document.location.href ;
}
When a request for the handler occurs with an expired session, it'll get redirected to the login page via forms authentication; when the login page is returned, it'll break your iFrame and redirect the full window to the login page.
Or, you can do what everyone else does, which is wait for the user to request another page.
For me, changing the timeout value in the web.config file to anything didn't take place, and the reason was there were somehow some leftover old records in the ASPStateTempSessions table in ASPState database. I had to empty the table and only then my web.config changes took place. I wasted an hour trying to search for the cause so hope this helps someone.
So, run this:
delete from ASPStateTempSessions
Difference between InProc and SQLServer mode is that SQLServer relies on MSSQL job to remove the session. It actively doesn't prevent you from login again.
See Session State Providers
SqlSessionStateStore doesn't actively monitor the Expires field. Instead, it relies on an external agent to scavenge the database and delete expired sessions—sessions whose Expires field holds a date and time less than the current date and time. The ASPState database includes a SQL Server Agent job that periodically (by default, every 60 seconds) calls the stored procedure DeleteExpiredSessions to remove expired sessions.

In a multi web server farm, how does session state work?

CASE 1: StateServer
<system.web>
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42626" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="20" />
...
</system.web>
CASE 2: SQL Server
<sessionState mode="SQLServer" stateConnectionString="tcpip=127.0.0.1:42626" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="20" />
Question:
1. In case 1 and 2 appropriate location of sql or state server have to be configured in web.config for each of the web server in farm.
Can we have some servers configured as state and some as sql?
Can we have some cookieless and some as withcookie
Suppose if we use only <sessionState cookieless="true" />, then by default which of the modes is used? Can this be done in a multiserver farm, or is it necessary to specify the IP?
1.) Can we have some servers configured as state and some as sql?
No, you should not. Suppose when a user makes a request, then one of the server from your Web Farm will store the session in a StateServer. now in case the same user makes another request ( by clicking some links etc...), then image what will happen if your load balancer send this request to the 2nd Web server ? There will be NO session for the same user as you configured SqlServer mode for the same and the session for the user was stored on a state server on First request.
2.) Can we have some cookieless and some as withcookie ?
Again NO, for a very similar understanding as pointed above. One of the server will use cookies to track the session and the other one Cookieless ( hence URI ) to track the same session and thus, if the request gets forwarded to different servers, NO session will be detected.
3.) Suppose if we use only <sessionState cookieless="true" />, then by default which of the modes is used? Can this be done in a multiserver farm, or is it necessary to specify the IP?
Understand that this setting: cookieless="true|false", is just used to TRACK the session for a Particular user between the Client side and server side.
The Actual session DATA is there stored on SqlServer/State Server, which is defined in your mode settings as:
<sessionState mode="StateServer|SqlServer" ... />
if you don't specify any mode setting, default value of InProc is used.
Additional Note:
The Cookie or the URI have a SessionID associated with them. SessionID is a unique string, used to TRACK individual visitor between visits to website.
As a result of cookieless="true", SessionID will be embedded in all page URLs. The drawback is that you'll end up with ugly URLs, which are not so good for SEO (search engine optimization) and visitor definitely will not remember it. Here is an example URL of website which uses ASP.NET cookieless sessions:
http://samplewebsite.com/(45f8c4zyybphaw2mt3dfgnjk4j)/Home.aspx
Bolded part represents session id, which is used to recognize a visitor.
Your question is a bit vague. If you're hosting one app across multiple servers I would recommend sticking to one method. What if one user first connects to a server with one mode, and the next request is handled by another one? The session state would not be accessible/known to the other server.
As to your questions, the documentation is really quite clear.
cookieless does not affect mode. If you don't specify mode, the default is InProc. If cookieless is true, ASP will use the query string.

How to create ASP.NET Membership cookie properly?

I'm using the Membership API for my login system and a wierd thing has been bothering me. I allow user to choose whether to "Remember Me", which means whether to create a persistent cookie with one month expiration period.
In the Web.config, I wrote:
<authentication mode="Forms">
<forms timeout="60" />
</authentication>
This is supposed to be a default session cookie of 60 minutes.
In the code behind of the login page:
if(Membership.ValidateUser(UsernameTextBox.Text, PasswordTextBox.Text))
{
authCookie = FormsAuthentication.GetAuthCookie(UsernameTextBox.Text, RememberMeCheckBox.Checked);
if(RememberMeCheckBox.Checked)
authCookie.Expires = DateTime.Now.AddMonths(1);
Response.Cookies.Add(authCookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(UsernameTextBox.Text, RememberMeCheckBox.Checked));
}
The result however is strange. I seem to have created a persistent cookie of 60 minutes! How is this possible?
You are setting the cookie expiration time to be be 1 month, but the authentication ticket that it contains has not been modified. It has inherited the default value of 60 minutes from your web config.
You likely want to synchronize cookie expiration with the authentication ticket expiration, or alternatively set the cookie to have a very long expiry date.
What you need to do is
create a FormsAuthenticationTicket instance manually and set the
Expiration property of the instance.
Use FormsAuthentication.Encrypt() to encrypt the ticket
Add a cookie to the Response.Cookies collection containing the ticket, manually. (rather then using get/setAuthCookie(), which uses
the web.config settings).
Some example code is in the documentation for FormsAuthentication.Encrypt().

Issues related to Session state off

In my web config I have session state off
<sessionState mode="Off" />
When I run my application I am seeing ASP.net_sessionid cookie being generated with expiration expiration "When I close my browser".
1 .How this cookie is generated if my session state is off?
How can I change the session timeout in this case (when session state is off)?
What is the relation between session timeout and the ASP.net_sessionid cookie expiry time?
If my session state is off will my Session End event in Global.asax.cs fire?
My guess is that the browser is displaying a cached version of the page. If it is IE check Tools - Options - General - Browsing History and click on the "Settings" button. Make sure that "Check for newer versions of stores pages" is set to "Every time I visit the webpage".

Controlling the FormsAuthentication createPersistentCookie expiration

In an ASP.NET MVC2 app, we have the standard login action...
if (ValidateUser(model.Email, model.Password)
{
FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
...
where the second parameter to SetAuthCookie is createPersistentCookie with the following documentation:
createPersistentCookie
Type: System.Boolean
true to create a persistent cookie
(one that is saved across browser sessions); otherwise, false.
We would like to have the persistent cookie expire after 2 weeks (i.e., a user could return to the site within 2 weeks and not be required to re-authenticate. After that time they would be asked to login again).
How do we set the expiration for the persistent cookie?
Can you not do this?
<system.web>
<authentication mode="Forms">
<forms timeout="20160"/>
</authentication>
</system.web>
The timeout is in minutes.
This timeout value is irrespective of whether or not you are creating a persistent cookie. It simply says that if you don't explicitly terminate the cookie (FormsAuthentication.SignOut), it will automatically expire after the given time period.
In other words, if you do:
FormsAuthentication.SetAuthCookie(someMembershipName, false);
Will result in the cookie expiring when:
The user closes the browser, or
The timeout is reached.
As opposed to if you do:
FormsAuthentication.SetAuthCookie(someMembershipName, true);
Will result in the cookie only expiring when the timeout is reached.
HTH
EDIT:
Take from MSDN:
the timeout attribute is described as follows:
Specifies the time, in integer
minutes, after which the cookie
expires. If the SlidingExpiration
attribute is true, the timeout
attribute is a sliding value, expiring
at the specified number of minutes
after the time that the last request
was received. To prevent compromised
performance, and to avoid multiple
browser warnings for users who have
cookie warnings turned on, the cookie
is updated when more than half of the
specified time has elapsed. This might
cause a loss of precision. The default
is "30" (30 minutes).
Note Under ASP.NET V1.1 persistent
cookies do not time out, regardless of
the setting of the timeout attribute.
However, as of ASP.NET V2.0,
persistent cookies do time out
according to the timeout attribute.
In other words, this expiration setting handles the Forms Authentication cookie only.
The Forms Authentication cookie is a client-side cookie, it has nothing to do with other server-side session you may have (ie a Shopping Cart).
That Session is expired with the following setting:
<sessionstate
mode="inproc"
cookieless="false"
timeout="20"

Resources