Manage sessions in multiple server environment - java

Suppose I have more than one web application servers running and I am logging in a User from Server1 thus his session starts.As http is stateless, suppose if the next request goes to Server3 than the Sever1 which was used to login to the application,if I use cookies, hidden form , its not going to work in Server2.
So how do I manage the session ?, maybe by generating an ID (or even reusing the jsessioid generated ) and storing it in a central database,so that all servers can access this session ID and validate it before processing the request.Then in that case, I need to develop a mechanism to store all the session data as object to the database.
Is there any other built in mechanisms available ?

If you are deploying application on more than one server, you should use "Clustering". Application servers are able to handle this scenario using "session replication". With session replication, each server will have a copy of the active users session. IF the first request goes to server A and second request goes to server B, it will be transparent to application code and end user.
For clustering/session replication in Tomcat, you can have a look at this link.

Spring provides the session management:
Spring Session makes it trivial to support clustered sessions without being tied to an application container specific solution. It also provides transparent integration with:
HttpSession - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way, with support for providing session IDs in headers to work with RESTful APIs
WebSocket - provides the ability to keep the HttpSession alive when receiving WebSocket messages
WebSession - allows replacing the Spring WebFlux’s WebSession in an application container neutral way
Source: Spring docs.
Please check this for further information: https://spring.io/projects/spring-session#overview

If your infrastructure ( Server 1, 2...) are connected to a single network appliance like Citrix Netscalar, then you can use IP or Cookie Persistence so that netscalar sends further requests to the same server.

Related

Which are the advantages of the Spring Session compared with Servlet HttpSession?

Which are the advantages of the Spring Session compared with Servlet HttpSession?
Where should I use the Spring session?
Spring Session do more advanced things than Tomcat HttpSession. HttpSession it's used in Servlets and Spring Session can be used in Servlets, RestApi...
Ex:
Why Spring Session and HttpSession
HttpSession actually is limited to a certain web container, which means its lifecycles are maintained by a container like Tomcat/Jetty. But when you have a couple of servers (normally a reverse agency like Nginx + several server instances), each server would have its own session, so a user will have to login more than once when successive requests hit different servers (e.g. Server A for the 1st time and server B for the 2nd time).
Keys to address this problem include:
1.Sync session informations among all server instances or
2.Maintain a global session
Actually Spring session aims at the 2nd solution, providing a global session management framework while supporting extensions with different 3rd-party persistence libraries like Redis/JDBC/In Memory.
Theoretically syncing sessions by yourself is also ok, but hard to maintain and time-consuming.
HttpSession
Provides a way to identify a user across more than one page request or visit to a Web site and to store information about that user. The servlet container uses this interface to create a session between
an HTTP client and an HTTP server. The session persists for a
specified time period, across more than one connection or page request
from the user. A session usually corresponds to one user, who may
visit a site many times. The server can maintain a session in many
ways such as using cookies or rewriting URLs.
More Info
Spring Session
Spring Session provides a transparent approach to resolving the
limitations of the HTTP session. It provides central session
management without being tied to container-specific solutions (e.g
Tomcat, Jetty etc.)...
Traditionally HTTPSession is container-specific i.e the container will
create a session and provide the session ID to the application. This
essentially means that if our application is running on a clustering
environment, each container will have its own HTTPSession management.
Session information is not shared across the different servers. The
session-id generated by application server 1 will be unknown to the
second application server.
More Info
Spring Session provides transparent integration with HttpSession. This
means that developers can switch the HttpSession implementation out
with an implementation that is backed by Spring Session.
More Info

How to track which server was chosen by Spring Cloud Netflix Ribbon (in Zuul)

I am developing a specialized, dynamic Web application router using Spring Netflix Eureka, Zuul, and Ribbon. I need to know what server was chosen by the Ribbon load balancer from the pool of servers registered with a given service id in Eureka for the request being routed.
It doesn't seem that Zuul tracks the server chosen by Ribbon in the RequestContext.
Context: This is not traditional stateless REST service routing. This router is managing pools of legacy Java Web apps that use unsharable (at the moment) sessions. These legacy servers are being retrofitted as Spring Boot Eureka aware applications. They will register with Eureka under a given server id. They will also register a GUID as Eureka metadata that uniquely defines that executing instance of the app.
I am implementing a sticky session scheme which will associate Java session ids with the unique server ids (the GUID) of the server that generated the session.
Thus when a request with a session cookie is received, I will use the Ribbon rule and predicate filter I've already written (for other reasons) to filter the list of servers to only the one who's GUID is associated with the session.
There may be other ways of doing this, but in my case, I have all the material I need except the knowledge of what server actually executed the request.

Password Access with Multiple Instances

I am designing an application that will require users to first login and then access several secure web pages. I plan on using AWS along with the AWS Load Balancer and expect several AWS instances of this application to be running. What is the "best practice" for persisting security credentials across several web pages and several instances? The user will login and then navigate through several secure web pages. I presume the AWS Load Balancer will be round-robin redirecting each https request to a different server instance. How does each instance know that the user has successfully logged in? Also, how do I keep the secure pages secure from external access? The platform will be Linux, Java, and Spring-boot.
I presume the AWS Load Balancer will be round-robin redirecting each
https request to a different server instance.
That's the default ELB behavior, but you can enable sticky sessions on the Elastic Load Balancer to lock a user to a specific back-end server, at which point the HTTP session stored on that one server keeps track of the user's authentication state.
How does each instance know that the user has successfully logged in?
They don't, unless you configure a shared session store of some kind. I prefer using Redis (ElastiCache) as a shared session store. Of course if you enable sticky sessions at the ELB that might prevent the need for a shared session store.
Also, how do I keep the secure pages secure from external access? The
platform will be Linux, Java, and Spring-boot.
That's not really a feature of AWS. You would need to add security to your application. Look into Spring Security.

Session amongst Angular and rest services on rails and java

How would you do session management for a website develloped in angular that consumes two types of REST services. The first is developped in ruby and the other is developped in Java Spring. For now I manage it with a shared table in a mysql database and a session id but i don't think this is the best solution.
A example of this problem is: how does the tomcat server knows about the session used by the rails application?
Thank you,
Davy
The REST servers should not do any session management.
they only get requests and responds to them. The client–server communication is constrained by no client context being stored on the server between requests.
How you are doing your session management in your application should not be affected by what resource provider you are using.
I agree with Philipp that a REST service should be as stateless as possible however I need some state in my appliation. (authentication)
I have found an article that gives the solution for my problem in this post about
session stickiness. This comes close to my situation of application servers on different machines and with different technologies.
In short they give 3 solutions:
maintain a session through cookies en session ids
use a database or cache
don't use a round robin technique but always let the load balancer send your request to the machine that stores your session. (not when you use diffent technologies)I.

Some questions about Websphere session management stratagy and session related content in Servlet 2.3 specification

In documentation Websphere Application Server Information Center - Clustered session support, it says
The session management facility requires an affinity mechanism so that all requests for a particular session are directed to the same
application server instance in the cluster. This requirement conforms
to the Servlet 2.3 specification in that multiple requests for a
session cannot coexist in multiple application servers.
Does it mean Websphere can only support sticky session(session affinity) mechanism? If not, how to config on Websphere to support non-sticky session stratage?
And In Servlet 2.3 specification, SRV.7.7.2 Distributed Environments
Within an application marked as
distributable, all requests that are part of a session must handled by
one virtual machine at a time.
Based on this specification, it supposes that we should follow this rule, but we can use non-sticky session stratage on Apache + Tomcat cluster, doesn't it break the rule?
Any response is appreciated.
Concerning your second question: If you use Tomcat behind an Apache server, you're using a component (The Apache server) that is not JEE compliant, thus it doesn't have to follow any JEE rules.
Concerning your first question, with Websphere you can choose between using the proxy server, the HTTP plugin, and implementing your own proxy solution:
http://pic.dhe.ibm.com/infocenter/clmhelp/v4r0m3/index.jsp?re=1&topic=/com.ibm.jazz.install.doc/topics/t_config_reverse_proxy_ihs.html&scope=null
http://www.ibm.com/developerworks/websphere/techjournal/1010_pape/1010_pape.html
You can ignore session affinity by means of the CloneiD property on the plugin-cfg.xml file
http://pic.dhe.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.nd.multiplatform.doc/info/ae/ae/rwsv_plugincfg.html
CloneID (zero or one attribute for each Server) If this unique ID is
present in the HTTP cookie header of a request (or the URL if using
URL rewriting), the plug-in routes the request to this particular
server, provided all other routing rules are met. If a CloneID is not
specified in the Server, then session affinity is not enabled for this
server.

Categories

Resources