I am not too sure about the feasibility of the requirement that I am trying to achieve, but here is how it goes:
I have created a Servlet that acts as proxy. It receives a RESTful call and then invokes another RESTful service on a remote server (node).
The forwarding is achieved via HTTPClient and not with a Request Dispatcher. I basically issue a new HTTP request to the remote server.
When the first server (proxy server) receives the call, the request (HttpServletRequest) has a session associated with it. The isNew() property of the HTTPSession is false.
When the call is forwarded and the remote server receives the call, the session gets to be a brand new one.
I am trying to basically find a way to forward the session to the remote server as well.
To be more precise:
Is it possible simply to get a session from a HttpServletRequest and put it into a session of a newly created HTTP request (via HTTPClient)?
It depends on how your remote WS maintains a session. If for example, it uses cookies (Tomcat does that amongst other techniques), then forwarding the incoming headers should help you achieve that (make sure that you mention that you accept cookies, but I thing HTTPClient does it by default).
Now, if it is based on parameter in the URL, then you should try to reproduce that behaviour.
If the two nodes (proxy and service) are separate processes that are not part of an application cluster, then probably not.
The servlet container typically manages the HttpSession. If you are forwarding a request to another service, hosted by a different container, then you will have a different session object.
If the two nodes are part of a cluster, then typically the session can be shared between nodes in the cluster via a number of mechanisms (in memory replication, database synchronization, etc).
Another option, is to externalize your session data into something like Redis, Memcached, Coherence, etc. Some application servers have pluggable support for such a process. I believe in this scenario the application server nodes would not necessarily have to be party of a cluster to share the session data.
I lacked some of the fundamentals of session handling when I asked this question. After some research and discussion here is what I got:
Basically, the sessions are handled by a JSESSIONID variable.
JSESSIONID is created automatically (can be turned off) when the request hits the server.
It gets sent back with in the response header.
The reason why the remote server thinks it is a new session is because the request doesn't have this JSESSIONID set.
The proxy does the following to ensure that the session is forwarded:
When the incoming request comes in; create and store the JSESSIONID.
Issue a new request to the remote server.
Unpack the response header from the remote server and extract JSESSIONID.
Maintain a mapping of client side JSESSIONID and remote server JSESSIONID.
For any of the following request, use this mapping to send requests to the remote server.
Basically, the proxy does the mapping from the client side's JSESSIONID to the remote server's JSESSIONID. This way, the session gets forwarded to the remote server.
Related
One of our Spring MVC web application is deployed on multiple web servers with tomcat 7 and LB is at front to balance and distribute the requests to appropriate tomcat server.
Problem with this web farming is each tomcat server is able to store and retrieve its own HTTP session, but LB can send requests to any one of web server. So if a user is served for login page through tomcatServer1 then it's HTTP session will be created on it's respected server and it may happen that for second request of dashboard page LB sends it to tomcatServer2 where HTTP session is not available, resulting user is again redirected to login page.
To overcome this,
we are using "Sticky Session" property on LB, so that if a user (HTTP session + user's public IP) is first time served from tomcatServer1 then it will get bound to that server. Setting "Sticky Session" is not helpful as it's not utilizing all servers equally.
Another way is, develop our own session state server and deploy on a server then all server should communicate to that server for storing and retrieving session object/data.
Providing custom SessionManager to Servlet Container.
About #2, If in case we able to develop state server then also I have to modify the code to related to HttpSession.setAttribute() and HttpSession.getAttribute(). So question is, is it possible to override implementation of HttpSession for methods setAttribute & getAttribute? Also About #3, I don't know whether this solution will provide distributed state session server?
I developed session state server for tomcat using python.
Due to this I don't need to change the code already written for creating/accessing and destroying session. Also as there is separate server/service which is handling and storing session so not master cluster is needed.
One of our Spring MVC web application is deployed on multiple web servers with tomcat 7 and LB is at front to balance and distribute the requests to appropriate tomcat server.
Problem with this web farming is each tomcat server is able to store and retrieve its own HTTP session, but LB can send requests to any one of web server. So if a user is served for login page through tomcatServer1 then it's HTTP session will be created on it's respected server and it may happen that for second request of dashboard page LB sends it to tomcatServer2 where HTTP session is not available, resulting user is again redirected to login page.
To overcome this,
we are using "Sticky Session" property on LB, so that if a user (HTTP session + user's public IP) is first time served from tomcatServer1 then it will get bound to that server. Setting "Sticky Session" is not helpful as it's not utilizing all servers equally.
Another way is, develop our own session state server and deploy on a server then all server should communicate to that server for storing and retrieving session object/data.
Providing custom SessionManager to Servlet Container.
About #2, If in case we able to develop state server then also I have to modify the code to related to HttpSession.setAttribute() and HttpSession.getAttribute(). So question is, is it possible to override implementation of HttpSession for methods setAttribute & getAttribute? Also About #3, I don't know whether this solution will provide distributed state session server?
I developed session state server for tomcat using python.
Due to this I don't need to change the code already written for creating/accessing and destroying session. Also as there is separate server/service which is handling and storing session so not master cluster is needed.
I have a bug in my JSP application. My session is cleared after post:
YAHOO.util.Connect.asyncRequest('POST', Url, callback, postData);
Before that call, all attributes are there, but after it they are lost.
I want to know what may be the reason for that.
The http session is maintained by the web server/browser by adding headers to the request/response that contains a SESSION_ID. The headers may be lost on the network before they reach the web server or web client. The web server creates a new session automatically if the request doesn't have the session ID.
Here's my situation, I have a web site that I just load using Apache HTTPD that then makes Ajax POST requests to a servlet which returns only JSON data. That JSON data is then used to update tables, etc..
Now I want to add user logic to my site, and also maintain servlet sessions for requests made by individual users.
I understand that the servlet needs to return the session id generated by the first call to request.getSession(), so that the client can add this sessionid to future Ajax requests in order for the servlet to know which session in memory to use.
I also understand that the two ways that this session id can be returned to the client is either using cookies (JESSIONID) or URL Rewriting.
If I can't use URL Rewriting, because I'm just returning JSON data, are cookies the only way I have left to send back the session id to the client?
Also, as a side question, currently I noticed that there is no JSESSIONID cookie in any of my HTTP responses from the servlet. Someone suggested to me that this was something new in Tomcat7 and that I had to activate them in the global context.xml. Does this mean that by default there is no session handling even if you make calls to request.getSession() ?
You have correctly identified two of the three ways of handling session IDs supported by Tomcat. There is a third way to track sessions but only if the application runs over SSL. In that case you can configure Tomcat to use the SSL session ID.
If the Servlet calls request.getSession() then Tomcat always includes a session ID in the response. However, those cookies are marked as httpOnly by default in Tomcat 7 onwards which means they are not visible to javascript (to protect against XSS attacks that try to steal the cookie). If the session cookies need to be visible to script then you need to set useHttpOnly="false" in either the web application's context.xml (to change the default for just that file) or in $CATALINA_BASE/conf/context.xml to change the default setting for every web application.
I’m developing a system to process financial transactions received by client merchants systems & it is a replacement of existing system which we have purchased from a vendor. Client interface should invoke the user authentication & transaction processing screens from our system.
System functionality as follows,
Receive input parameters from the merchant’s site
Validate it
Authenticate users (users are registered with our system & we should invoke our login screen)
Process transaction
Return status response to merchant
One the response is received client should validate the transaction data from the values reside in the session.
System overview can be depicted as follows,
(click here for full size image)
My problem is client could not retain the session once we are responding to the client. But the same functionality could be achieved by the system that we have purchased from the vendor (we don’t have source code of this to analyse the internal coding structure). I hope something wrong with the way that we are responding to the client.
How can I overcome this problem?
We are using Java 1.4.2, Websphere application server
There are many things which can make a session disappear. I'd suggest to track them and verify if anything went right. This is easier to do if you understand how sessions work.
Session has been timed out. This usually defaults to 30 minutes. This is confiugureable by <session-timeout> in web.xml where you can specify the timeout in minutes. You can implement a HttpSessionListener to track session creation and destroy using a logger.
Session has forcibly been invalidated. This happens when the code calls HttpSession#invalidate(). This is trackable with a HttpSessionListener as well.
Session cookie has been disappeared. Sessions are backed by cookies. If a session is been created, the server will add a Set-Cookie header with session ID. The client should send the same cookie back as Cookie header in all subsequent requests on the (context) path as specified in the Set-Cookie header. This is trackable in the HTTP traffic monitor ("Network" tab) of browser's builtin web developer toolset (press F12 in Chrome/Firefox23+/IE9+). Cookies are accessible for all webapps on the same cookie domain. Also, if ServletC2 runs on a different webapp context than ServletC1, then it won't use the same session. Further, if the "server" webapplication runs on the same domain, then it's in theory able to wipe out all cookies of the "client" webapplication.
The client doesn't support cookies. A well designed webapplication uses URL rewriting with jsessionid to track cookieless clients between requests on the same webapplication. But the second webapplication has to do the same when redirecting back to the first webapplication.