How to keep client session alive in spring MVC after server disconnection - java

I am working on Spring MVC application. Usually face a problem that when server get down the client session get expired.
So, I want to make session alive. When server goes up then client not need to login again.
Can we save cookie id or session id in database to make client reconnect.

could it be what you are looking for?
how-can-i-make-the-spring-security-stores-the-http-session-in-database-so-i-can
here is the link to the blog-article:
Tomcat 7 JDBC Session Persistence

If you are using spring security, you can have your own implementation of SecurityContextRepository (By default this is HttpSessionSecurityContextRepository) to persist the session content in database. In this way when user presents his cookie the security framework filter (SecurityContextPersistentFilter) will look at your database for the session. Hence, even when server is down the context is still available in database and is loaded during next user request after server restart.
If session persistence is not an option, you may have to deploy a cluster of servers with session replication strategy.

The purpose of remember me is altogether different. It's not to have session across server restarts, but for across restarts in client (browser). Even with remember-me you can not get it across server restarts, unless you use PersistentRememberMeService (to database)

Related

Spring boot security avoid specific user session expire

Hello everyone I've got my spring boot application on Apache Tomcat server and it works fine. But now I need to avoid session expiration for an specific user. How could I do that? I've been searching ways and found that handler interceptor could be useful for session management but I'm not sure.
Thanks in advance!
I am afraid there is no simple way to do it. Expiration timeout is common for all users of your application and controlled by the application server. In order to have a different timeouts for different users you should:
implement some session wrapper over a native server session;
set expiration timeout for native server sessions to the longest time that you will give to one of your user sessions;
manage expiration timeout of your session wrappers by your own.
EDIT: In my opinion the best way to solve this issue is reconsidering of client's requirement (immortal user with admin rights is a bad idea for your application). Anyway customizing of security related parts of application is always risky and you should really know what you do.

Getting hold of replicated session objects in Java / JBoss

I have an application deployed with JBoss on two machines in a cluster. When a user logs into one application server, I've validated that the session is replicated to the other cluster (logging in with the same cookies to the other server confirms this).
JBoss handles this replication automatically with Infinispan and JGroups for caching and messaging respectively. My issue is: How can I get a handle of each replicated session in the second server?
The normal way nowadays to manage HttpSession instances is by implementing the HttpSessionListener interface which calls a sessionCreated(HttpSession s) method whenever a new session is added. This works fine for the first server, but this does not work in the second server because: the session in server 1 is serialized, copied over, then de-serialized in the second server, which bypasses the constructor and therefore does not allow the session to be registered to the HttpSessionListener listener.
Is there another possibility to get a handle of a session as it is replicated? Could I perhaps listen for de-serialization events (is that even possible) or do something else?

Overriding Servlet container session storage

If want to store my web application session to different storage, because one every new request user might use different node, is it possible to override default container session storage?
You do not need to overrride anything. It should come with the server you are using. You need to look at "Session replication". In clustering environments, the app server can be configured to replicate session across nodes.
You will need to check documentation of the app server you are using to figure out how this can be enabled.
Please checkout the memcached-session-manager. It stores the session in external memcached server and works for both sticky-session and non-sticky-session(which is your case) scenario.

Creating a session with specific session ID

thank you you guys for looking at my post.
Due to grey areas in licensing issues, I have two instances of tomcat running. I'm using Apache proxy to seamlessly communicate between the two.
App1 lives in tomcatA.
App2 lives in tomcatB.
Both requires user authentication and uses sessions for storing data. App1 is the only one visible to outside world and all the requests that comes in to App2 are generated by JavaScripts from App1. Unfortunately, App1 has a session and sends that specific JSESSIONID to all the requests from App2. Since there isn't a session with that specific id in App2, it returns with errors.
Is there a way for me to initialize a session with specific id?
Is there a way for me to modify all the requests so that it puts the valid session id into the headers.
Edit: I need App2 to realize that requests coming through, from App1, with a particular session id maps to a session that App2 created.
Even if both application lived in the same Tomcat, sessions would be different as they are issued on a per-app basis. Personally, I am not entirely convinced by this design.
If your question is how to propagate authentication to another app, use a single sign-on application like Josso or a CAS; to share session data, you can use a centralized cache accessible from both applications and accessible through JSON.
And yes, session data is bad.
Update: can't you simply implement a handshake protocol like: app2/register/{app1 session id} - at this point you both hold both session ID's and you can correlate each other. This can be done also with a session listener.
You could just use a different session cookie name (or path, if possible) for your tomcatB. tomcatB would thus consider the JSESSIONID cookie as any other cookie, and not as a session cookie.
See http://tomcat.apache.org/tomcat-7.0-doc/config/context.html.

Using tomcat in round robin mode

I want to run my tomcat-instances in a configuration where requests are served to several tomcat-instance via round robin. I don't want to use any internal cluster manager.
As far as I see if every request is served by different tomcats, an unknown sessionId would arrive at a tomcat, so it would be forced to create an new session and overwrite the old sessionId. So for every request a new session would be created. This seems to be a lot of overhead.
Is my view on that things right? Is there a way to disable tomcats sessions management?
Regards,
Michael
Basically you have two choices:
1) Replicate your sessions so they become reachable by any Tomcat node. Solutions: Tomcat Cluster, memcached-session-manager, possibly others.
2) Use a load balancer and implement sticky sessions. First requests will be routed randomly on a round robin basis, but subsequent requests will stick to the same server. Solutions: mod_proxy, hardware traffic managers.
The disadvantage of the first option is that session replication is costly, not very reliable and often requires Serializable-only data to be put in session.
The disadvantage of the second approach is that if you shut down your Tomcat for maintenance, the users will be forced to log in again.
You are incorrectly assuming that "for every request a new session would be created". The new session will be created only if not created before on that same server, or if it was created but already expired.
We usually used Tomcat behind an Apache web server with mod_jk for load balancing the requests across the Tomcat instances.
With sticky sessions a user will only get a session upon the first request and will afterwards always be directed to the Tomcat from where his session originates. So there is no need to replicate sessions across all Tomcats and the requests will be distributed across the Tomcats, too.
Of course, this does not ensure some kind of round-robin which you asked for.
A session will only be created once your code requests the session so if your application doesn't require the session then just simply dont access it. Checkout the section on getSession() in HttpServletRequest
http://download.oracle.com/javaee/5/api/javax/servlet/http/HttpServletRequest.html#getSession(boolean)
I'm not sure if there is a way to replicate the session across different tomcat instances however if you require some user state without session then you can use cookies instead.
EDIT: If you do need to replicate the session you could probably start by reading this tomcat document.
http://tomcat.apache.org/tomcat-5.5-doc/cluster-howto.html

Categories