What algorithm Spring Session use to generate the session id [duplicate] - spring

This question already has an answer here:
Uniqueness of Session ID in a Distributed environment?
(1 answer)
Closed 2 years ago.
What algorithm Spring Session use to generate the session id? If I have multiple application instances running behind a load balancer, does it guarantee the session id is globally unique? if not what would be the solutions to make it globally unique without using session/IP affinity?

A session ID is a unique number that a Web site's server assigns a specific user for the duration of that user's visit (session). The session ID can be stored as a cookie, form field, or URL (Uniform Resource Locator). Some Web servers generate session IDs by simply incrementing static numbers. However, most servers use algorithms that involve more complex methods, such as factoring in the date and time of the visit along with other variables defined by the server administrator.
Every time an Internet user visits a specific Web site, a new session ID is assigned. Closing a browser and then reopening and visiting the site again generates a new session ID. However, the same session ID is sometimes maintained as long as the browser is open, even if the user leaves the site in question and returns. In some cases, Web servers terminate a session and assign a new session ID after a few minutes of inactivity.

Related

Coldfusion 2018 clustering and session replication not working

Setting up a couple new Coldfusion 2018 servers and will be using clustering for the first time and have run into some problems.
I am having trouble with session replication. Basically, session variables appear to be replicated between nodes in a cluster but are killed after a short while at random.
A little setup info:
2 web servers (Windows Server 2012) behind load balancers
On each web server sits a Coldfusion cluster consisting of 2 local instances (still unclear if this is useful or not - will ask in separate question) and 2 remote instances (the remotes reference the local instances of each opposite server)
For simplicity, currently just testing on a single server with local Coldfusion instances - leaving the remotes out of the equation until I can get things working reliably locally
Using J2EE session variables
Coldfusion session timeout set to 2 hours
In each Coldfusion instance, channelSendOptions is set to "6"
Here is what I did/experienced:
We have a web application that requires login and stores user information in the session upon login.
I made a small modification to the web app to show me which cluster instance has serviced my current request.
After setting up the cluster, I started the web application and logged in, noting the instance which displayed the login page.
Upon logging in, I was immediately returned to the login screen (app checks for user info in session and redirects to login if not found)
Debugging revealed that I was actually being logged in but after redirecting to some new page after login the user info would be gone from session.
Multiple login attempts in a row (same credentials, just tried over and over again and again) revealed that sometimes login would proceed just fine and I would get into the app. However, if I refreshed the page or went to another page, the session would be lost very soon but at random (within a few page refreshes).
In an attempt to simplify the problem to try and figure out what is going on, I created a simple .cfm that bypasses all the login stuff and does one thing: adds a simple string value to session and then dumps the session and instance name.
** I ran the script once, noted which instance was being used and that session contained my value.
** I then edited the script so it no longer set the session value.
** I then hit refresh over and over so I could confirm:
That requests were being serviced by both instances in cluster
That as I flip-flopped between instances, the session value was available all the time.
Again, the replication would work and for several refreshes I could see my session variable available on each instance...until it wasn't. After a random number of refreshes/seconds (between 2 - 10 refreshes say) the value would disappear.
I am at a loss to explain why this is happening. We considered using Redis as a session store to see if it helped but frankly, our team has no experience with it, it is clunky to get working in Windows and we really don't want any more moving pieces in our infrastructure if we can help it.
Any insight on what is occurring as well as advice for how to peer behind the scenes as it were and see what is going on with session replication would be greatly appreciated.
Thanks
Adding some code and screenshots. The screenshots show the state of session after each page refresh and which instance is currently serving the page. The last two images represent refreshes 11 and 13 - the session variable was lost in 11 and I went to 13 so that we can see that the variable was lost on the other instance as well. Also a couple pictures of cluster/session setup.
Following is the simple test script. The first line is un-commented on first run to create the session variable and commented out for each subsequent run.
<!--- <cfset Session.svar="cake!"> --->
<cfdump var="#Session#" />
<cfscript>
hostaddress = createObject("java", "java.net.InetAddress").localhost.getHostAddress();
</cfscript>
<cfoutput>
<h3>
Instance: #createobject("component","CFIDE.adminapi.runtime").getinstancename()#
</h3>
</cfoutput>

Spring Session Repository List All

I need in my project more session management than I thought at the beginning. The major feature that I need is to list all sessions for (or per) identified principal (for example to delete/invalidate all his session id's). I don't want to use SessionsRegistry because of distributed kind of a system.
So two questions:
How to list session ids in Spring-Session (Do I need to come with custom implementation) ?
Is there a way to set sessions time-out that is not interval between requests but max session time life?
Typical use case for such functionality is to prevent malicious user to continue his activity by blocking his account and invalidate his all sessions across the servers.

InProc session state, web farm and unique and sticky SessionID?

I'd like to have InProc session state on servers in my webfarm and only share the unique SessionID (which I believe is transferred via browser cookie).
Is this possible? We're planning to have custom object cache based on this SessionID that needs to be loaded only in certain scenarios. If possible, I'd like to avoid creating custom session provider
You really should avoid relying on internal details of ASP.NET (how it manages Session ID) - this behavior could change in the next .NET version or even before that if someone discovers a vulnerability in the current approach.
Instead create your own cookie - both reading and writing that cookie is a one-liner (HttpResponse.SetCookie() and HttpRequest.Cookies[]).

Persisting user data in MVC 3

I have been given a requirement to persist user data once the user has authenticated initially. We don't want to hit the database to look up the user every time they navigate to a new view etc...
I have a User class that is [Serializable] so it could be stored in a session. I am using SQL server for session state as well. I was thinking of storing the object in session but I really hate doing that.
How are developers handling this type of requirement these days?
Three ways:
Encrypting data in cookies and sending it to client, decrypting it whenever you need it
Storing it server side by an Id (e.g UserId) in Cache, Session, or any other storage(which is safer than cookie).
Use second level caching strategy if you used an ORM
Assuming your user object is not huge and does not change often i think it is acceptable to store it in the session.
Since you already have a sql server session you will be making SP calls to pull/push the data already and adding a small object to that should have minimal perf issues compared to other options like persisting it down to the client and sending it back on every request.
I would also consider the server a much more secure place to keep this info.
You want to minimize the number of times you write to the session(request a lock) when it is stored in sql as it is implemented in a sealed class that exclusivity locks the session. If any of your other requests in this session require write access to the SQL session they will be blocked by the initial request until it releases the session lock. (there are some new hooks in .NET 4 for allowing you to change the SessionStateBehavior in the pipeline before the session is accessed)
You might consider a session state server (appfabric) if perf of your SQL session store is an issue.

What's the best way to share "session" information between 4 datacenters with 40 servers?

Currently our DNS routes the user to the correct datacenter and then we have a round-robin situation for the servers. We currently store the session information in the cookie but it's grown too large so we want to move it out of the browser and into a database. I'm worried that if we create a midteir box that they all hit that the response times will be affected. It's not feasible to store the session info all all machines because we're talking about 200M+ unique sessions a month. Any suggestions, thoughts?
A job for memcached or, if you want to save session data to disk, memcacheddb
Memached is a free & open source, high-performance,
distributed memory object caching
system, generic in nature, but
intended for use in speeding up
dynamic web applications by
alleviating database load.
Memcached is an in-memory key-value
store for small chunks of arbitrary
data (strings, objects) from results
of database calls, API calls, or page
rendering.
Memcached is simple yet powerful. Its
simple design promotes quick
deployment, ease of development, and
solves many problems facing large data
caches. Its API is available for most
popular languages.
Let's understand the role of browser-based cookies
Cookies are stored per browser
profile.
The same user logged on from different computers or browsers is
considered different users.
State cookies are mixed with user cookies
Segregate the cookies.
Long-term state cookies, e.g. the currently-remembered userId.
session state cookies
user cookies
Reading that your site is only beginning to consider server-side cookies implies that a segregation of cookies has not yet been done. User cookies should be stored on server as much as possible, so that when a user logs on at another computer or browser, the preferences and shopping carts are preserved. Your development team has to decide for some cookies, for example shopping carts, to be between being session-state or user info cookies.
User cookies
Need to be accessible across the web site, regardless where the user logs in. Your developers have to decide, when a user updates a preference or shopping cart, how immediate should that change be visible if the same userId is logged in at another location.
Which means you have to implement a distributed database system. You have a master db server. Let us say you have 20 web servers, each server with its own database.
Store only frequently changed cookies on the local db and leave the infrequently changing cookies on the master.
Everytime a cookie is updated at a local db, a updated flag is queued for update to the master. The cookie record in the master is not updated, only marked as stale with the location number where the fresh data resides. So that if that userid somehow gets activated 3000 miles away simultaneously, that session would find out the stale records and trigger a request to copy from those records from the fresh location to its own local db and the master db and the records no longer marked as stale on the master db.
Then you schedule a regular sync of most frequently used cookies. The frequency of sync could be nightly or depends on the result of characterization of cookie modification.
First, your programmers would need to write a routine to log all cookie read/writes. You should collect a week's worth of cookie read/write activity to perform your initial component analysis.
You perform simple statistical characterization per cookie, userid and frequency of change. Then you slide along your preferences deciding which cookie is pushed to all the local dbs and which stays on the master. The decision balances between the size of the cookie block on the local dbs and the frequency of database sync you are willing to allow. Which means not every user have the same set of cookies propagated. of course, your programmers would need to write routines to automate the regular recharacterization. Rather than per user, you might wish to lighten the processing load of cookie propagation by grouping your users using cluster analysis. May be the grouping of users for your site is so obvious that you need not perform cluster analysis.
You might be surprised to find that most of the cookies could fall into the longer-than-weekly-update bucket. Or the worse case, daily-update. and the worst case you should accept is hourly update for cookie fields which are not pushed onto the local dbs. You want to increase the chances that a cookie access occurs on the local db rather than being pulled from the master database. So when a user decides to click on "preferences" which is seldom changed, you preemptively pull the preferences records from the master while distracting the user with some frills like "have you considered preview our new service?", "would you like to answer our usability survey?", "new Gibson rant, would you comment?", etc until the "preferences" cookies are copied over.
The characterization of cookies could be done per userid, or per cluster of users to decide which cookie field to push around to local dbs.
It is more simplistic to characterize per userid because it barely involves any statistical analysis skills on the part of the programmer. The disadvantage is that the web server would have to perform decisions for each of 200 million users. The database cookie table would be
Cookie[id, param, value, expectedMutationInterval].
You web server would decide per user which cookie push regularly by the threshold time.
SELECT param, value
WHERE expectedMutationInterval < $thresholdTime
AND id = UserId
You have to perform a regular recharacterization of cookies to update expectedMutationInterval per user per cookie. A simple SQL query would be able to perform the update of expectedMutationInterval. A more complex analysis could be performed to produce the value expectedMutationInterval.
If each cookie field change is logged by time, userid and ipaddr then your Cookie log table would be
CookieLog[id, time, ipaddr, param, value].
which would help your automated recharacterization routine decide what fields to push depending on the dayofweek/month/season and location/region/ipaddr.
Then after removing user info cookies from the browser, if you still find your sessison cookies overflowing, you now decide which session cookies to push to the browser and which stays on the local server. You use the same master-local db analysis technique but now used to decide between local db and pushing to browser. You leave your least frequently accessed session cookies on the local server, either as session attributes or on in-memory db. So when a client finds a cookie is missing, it makes are request to the server for the cookie while sacrificing some least recently/frequently used cookie space on the browser to accommodate placing of that fresh cookie.
Since these are session cookies, they need be propagated to other locations because if a same userid is logged on 3000 miles away, it should have its own set of session cookies.
Characterization of browser cookies are an irony because, for AJAX apps, the client accesses the cookies without letting the server know. Letting the server know might defeat the purpose of placing the cookies in the browser in the first place. So you would have to choose idle times to send cookie accesses to the server to log - for characterization purposes.
Such level of granularity is good for cookies that are short in lengths (parameter value + parameter name), be it session based or user based cookies.
Therefore, if your parameter names and values of cookie fields are long, you might seek to quantize them.
However, quantization is a little more complex. Browser cookies have a lot of commonality. Just like any quantization/compression method, you look for the clusters of commonalities and assign each commonality block a signature. Then the cookies are stored in terms of the quantized signature.
How do you facilitate quantization of browser-based cookies? Using GWT as an example, use the Dictionary or Map class.
e.g., the cookie "%1"="^$Kdm3i" might translate to LastConnectedFriend=MohammadAli#jinnah.
You should not need to perform characterization, for example, why store your cookie as "LastConnectedFriend" when you could map it to "%1"? When a user logs in, why not map the most frequently accessed friends, etc, and place that map on the GWT/AJAX launching page? In that way you could shorten your session cookie lengths.
So, is your company looking for a statistical programmer? Disclaimer is, this is written off-the-cuff and might need some factual realignment.

Resources