Whats the difference between Cookie SESSION= and session_id in database for spring session - spring-jdbc

I am using spring session with JDBC postgres for session management. Whenever a new session gets created spring creates it and send the sessionid back to the browser in the cookie parameter SESSION and browser sends it back for every subsequent requests and things work fine. But the value in session_id in the postgres table spring_session is different form the SESSION sent back initially in cookie. Is this the expected behavior ?

Yes, this is expected.
Starting with Spring Session 2.0, DefaultCookieSerializer uses Base64 encoding by default. So what you're actually seeing as session cookie value is the Base64 encoded session id.
If you wish to restore the previous (Spring Session 1.x) default, you can explicitly configure DefaultCookieSerializer bean with useBase64Encoding property set to false.

Related

when does a session get created in any asp.net web application?

Does a session get created for every page request ? even though we don't have any forms authentication enables or any session objects created in the application ?
From Microsoft Docs:
The SessionID property is used to uniquely identify a browser with session data on the server. The SessionID value is randomly generated by ASP.NET and stored in a non-expiring session cookie in the browser. The SessionID value is then sent in a cookie with each request to the ASP.NET application.
So, when a browser requests a resource which requires session state, if the Session State Module cannot find an existing session ID (either in the ASP.NET session cookie, or in the URL in the case of cookieless sessions), then a new session ID is created and returned in the session ID cookie.
The session ID is used to retrieve a set of session state values (commonly known as "session variables"). Data stored in such a "variable" will remain available as long as the session exists. If the session times out, or if the AppDomain restarts, or if the cookie becomes unavailable, then the session "variable" will contain null. Code using session state must be prepared for this:
bad code:
string user = Session["User"];
int length = user.Length; // NullReferenceException if session was expired
better code:
string user = Session["User"];
if (user == null) {
// Do without the user information
} else {
int length = user.Length; // User information is available
}
Session state data is shared across all the data forms but for the sing user global data.
Declaration For the session :
Session["Key"] = "value";
Session data are stored on the server side.
Session state variables are declared when session times out.
By default time out for session is 20 minutes.
For Example :
**If you are using session & you are executing the first session web form & suppose you have navigated your page from web-form 1 to web-form 2.
Then Session output will be the same.
If suppose your o/p for web-form 1 is "2".
Then if you have closed the browser & copy and paste the same URL to another browser.
then you will notice that o/p will be the same Because In your URL session ID is present.
there for it will have the same o/p.
This is very Important to understand about session if you want to use the session in your application.**
ie session data session state data shared across all the web-form but only fr single user.
For every session Unique session ID is generated.
But is you have changed your session then new session ID is generated meaning it is only for single user.

Asp.Net: Retaining the old browser session after closing and reopening browser instance

Is there a way I can retain the browser session after the user has closed his browser and then reopens.
The default behavior in asp.Net is that it keeps the Asp.Net SessionId in the browser cookie which expires when we close the browser. On reopen the browser asp.net generates a new SessionId and even if the old session is not expired on the server side we can not retain it.
Can we control the expiration behavior of the session cookie in Asp.Net?
You cannot reclaim the session-id as such, but you can certainly restore some of the predictable part of the session state. If you are using forms authentication, then just read the forms-auth cookie in global.asax session start and re-populate the session objects.
You can control the expiration of forms-authentication cookie manually by creating a persistent cookie by using:
FormsAuthentication.SetAuthCookie(userName, true)
Alternatively, you can fine-tune the expiration by manually changing the cookie:
Dim authCookie As HttpCookie = FormsAuthentication.GetAuthCookie(userName)
Dim authTicket As FormsAuthenticationTicket = FormsAuthentication.Decrypt(authCookie.Value)
Dim newAuthTicket As New FormsAuthenticationTicket(authTicket.Version, authTicket.Name, authTicket.IssueDate, expireDate, authTicket.IsPersistent, userData)
authCookie.Value = FormsAuthentication.Encrypt(newAuthTicket)
authCookie.Expires = newAuthTicket.Expiration
HttpContext.Current.Response.Cookies.Set(authCookie)
Where expireDate specifies when the cookie should expire.
Now in global.asax session start you can check if the returning user is still authenticated (by virtue of persistent cookie previously set):
If HttpContext.Current.User.Identity.IsAuthenticated Then
' Here re-populate the predictable part of session state
' Like user profile etc.
End If
Added after Op insights:
Forms authentication is not being used, and the aim is to be able to just restore the previous session.
In such a case the only option is to persist the existing session by way of a persistent cookie, so that you can retrieve it later. There are some workarounds to achieve this. One of the workarounds is explained here by this blog writer:
http://weblogs.asp.net/imranbaloch/archive/2010/06/09/persisting-session-between-different-browser-instances.aspx
What is happening here is that we intercept two events in the global.asax:
PostRequestHandlerExecute: (Occurs when the ASP.NET event handler finishes execution) In this handler, we create a new cookie (say temp), value of which is assigned the value of current SessionId. We make it a persistent cookie by setting the expires property to the session timeout.
PostMapRequestHandler: (Occurs when ASP.NET has mapped the current request to the appropriate event handler) In this handler, we check the returning user by checking the existence of the "temp" cookie. If found, we update the actual session cookie (ASP.NET_SessionId) with the value of our "temp" cookie; thereby effectively restoring the previous session.
Please note that this is just a workaround. The system is designed to create a new session. All we are doing is to use a few hooks to workaround this by persisting an existing session to retrieve it later. All security implications stand.
At the Least you can retrieve Session information. This can be done easily when you set the 'Mode' to "SqlServer".
You can Query the Database (ASPState) & hence the table (ASPStateTempSessions) where you are storing your Sessions.[ I used persistent storage: -sstype p ]
SELECT TOP 5 [SessionId]
,[Created]
,[Expires]
,[LockDate]
,[LockDateLocal]
,[LockCookie]
,[Timeout]
,[Locked]
,[SessionItemShort]
,[SessionItemLong]
,[Flags]
FROM [ASPState].[dbo].[ASPStateTempSessions]
Even if you know your sessionID, you may use it to restore your previous session. Asp.Net will generate a new SessionID when you do a new request.

How to get session value in code file while session is created in httphandler

How to get session value in code file while session is created in httphandler .it gives error like Object reference not set to an instance of an object.
The session is connected with a page request, to work is require to read the cookie of the user from the browser, or the url in case that is with out cookies.
So in the asp.net session if you do not have the httphandler, you can not have the session, because you can not know who is calling and see the page at that time.
Maybe in a custom solution session, you can send the session id to some other code with out the httphandler and use that id to read the session data, but the asp.net did not give this option.

cookies and the session state object

Anyway, my main concern is using Session. I've always been under the impression that if you use the following statements (not that I would):
Session["newVar1"] = "a new session variable";
Session["newVar2"] = "a new session variable";
Session["newVar3"] = aLargeVariableThatHoldsLotsOfData;
You would be creating 3 new session cookies that hold the particular value. But I think my asp book is indicating that you would actually create 3 new variables in your session state object and ASP would only pass a unique Session ID (as a cookie?) in the response, and would get this ID upon the next request and associate that ID with your Session State Object (that IIS has stored in memory..?):
...it creates a session state object
that contains a unique session ID for
each user's session. This ID is passed
back to the browser as part of the
response and then returned to the
server with the next request. ASP.NET
can then use the session ID to get the
session state object that's associated
with the request.
That doesn't seem ideal for a website with lots of traffic. A server that is storing and maintaining thousands and thousands of instances of session state per website seems like way too much overload.
I'm trying to see what's going on on my own, but I'm having trouble.. I can't find my site's cookies anywhere on my machine (IE/windows xp). I've checked C:\Documents and Settings\nicholasr\Cookies\ and C:\Documents and Settings\nicholasr\Local Settings\Temporary Internet Files which, according to this yahoo answer, IE cookies are stored as well. I'm using ticket authentication in my app which stores a auth cookie on the client, so a cookie from my site has to be somewhere..
I guess I'm asking:
1) If someone can help me understand how Session State works behind the scenes
2) Where is IE storing my site's cookies? ><
There is a single session cookie which represents a GUID. The session values itself are stored on the server. So when you write:
Session["newVar1"] = "a new session variable";
Session["newVar2"] = "a new session variable";
Session["newVar3"] = aLargeVariableThatHoldsLotsOfData;
an HTTP cookie that might look like this is sent to the client. This cookie contains only an id, not the actual values. The actual values could be stored either in the server memory, a separate process, or even SQL Server depending on the <sessionState mode="" in web.config. Then when later the client sends another request it will send this cookie id to the server and given id the server will fetch the actual values.
The client browser stores those cookies in memory, meaning that if you close it, the session will be lost because session cookies are not persistent.

Can I abandon an InProc ASP.NET session from a session different than one making the request?

We have an application that does single sign-on using a centralized authentication server (CAS). We'd like to do single sign-out, such that if the user logs out of one application (say a front-end portal), the user is automatically signed out of all applications using the same single sign-on ticket.
The expectation would be that each application would register a sign-out hook (URL) with the CAS at the time of logon to that application. When the CAS receives the sign out request from one of the applications, it invokes the sign-out hook for all the application sharing the SSO ticket.
My question is this: is there a way to abandon an InProc session from a different session? I presume, since the HTTP request will be coming from the CAS server, that it will get its own session, but it is the session of the user that I want to terminate. I have pretty good idea of how to do this using a separate session state server, but I'd like to know if it is possible using InProc session state.
Haha, well... It looks like you can. I was wondering myself if there was any way to do this, turns out, there is.
When you use InProc, the InProcSessionStateStore (internal class) persist the session state in an internal (non public) cache. You can access this cache through reflection and remove the session state manually.
using System;
using System.Reflection;
using System.Web;
object obj = typeof(HttpRuntime).GetProperty("CacheInternal",
BindingFlags.NonPublic | BindingFlags.Static)
.GetValue(null, null);
if (obj != null)
{
MethodInfo remove = obj.GetType()
.GetMethod("Remove", BindingFlags.NonPublic | BindingFlags.Instance,
Type.DefaultBinder, new Type[] { typeof(string) }, null);
object proc = remove.Invoke(obj, new object[] { "j" + state.SessionID });
}
The end result is, that the next request will take on the same SessionID, but the HttpSessionState will be empty. You'll still get the Session_Start and Session_End events.
After doing a bit of digging around and considering the answers provided so far I've come up with an alternative that lets me continue to use InProc session. Basically, it consists of extending the HttpModule that already handles single sign-on to detected CAS sign outs and redirect the browser to the application sign out page.
Outline:
Sign-On:
For each new single sign-on request, create a new SSO cookie and encode a unique value in it to identify the session (not the session id, so it isn't leaked).
Construct the the sign-out callback url, encoded with the identifier, and register it with the CAS server.
Sign-Out:
When a sign-out request is received from the CAS server, decode the identifier and store it in an application-wide cache. This needs to be pinned in the cache at least long enough for the session to expire naturally.
For each request, look for the SSO cookie and check its value against the cached, signed-out session identifiers. If there is a hit, remove the SSO cookie and redirect the browser to the application's sign-out url.
For each sign-out, check to see if there is an SSO cookie, if so, forward the sign-out request to the CAS. In any event, abandon the user's session, and sign them out of the application.
Page_Load:
Check for the presence of the SSO cookie. If there isn't one, redirect to the sign out page.
No can do.
http://forums.asp.net/p/416094/416094.aspx#416094
With InProc SessionState, you won't be able to access the data... With StateServer, you still will have a sticky scenario trying to access the correct API to remove the session.
You will most likely want to use a database backed state solution like the pre-packaged SqlServer state provider or a third party solution like DOTSS: http://codeplex.com/dotss
With the database backed solution, you will be able to lookup the state record in a table by session id and mark it as completed. These techniques will vary based on the provider you choose.

Resources