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.
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.
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.
We have a Tomcat server for a web shop, and we need to transfer the user to another (secure) server when he/she logs in. Here's a detailed explanation:
1) We have two Tomcat servers: one 'regular' (HTTP) and one secure (HTTPS)
2) Users initially visit the regular server
3) When they log in, we need to get their log in data, as well as the information about what page they were currently on (or were trying to see), pass it to the secure server and do the actual login; for instance, a non-logged in user sees a list of products, clicks 'BUY' and a popup is displayed, asking the user to log in; the user enters his/hers credentials and these, as well as the information about what product he wants to buy, are passed to the secure server; the secure server receives these, performs the login and displays the requested product to the user
How could this be done? Please note the following:
1) We've tried doing it with cookies, but we've decided not to go that way
2) Persisting the session to a database and then having the secure server fetch it is also not an option
Are there any other ways? We were thinking about creating an object and then passing it as a HTTP POST parameter, but I'm not sure how this could be done (I've been given the task to finish it).
For what it's worth, the technologies we use are Tomcat server, Wicket, Spring, iBatis and MySQL.
Thanks in advance :)
If you want to share the session between different Tomcat instances, you could configure them to work as a cluster with session replication: http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html
Then, you could configure an Apache HTTP Server to work as a load balancer, making sure that HTTP requests go to server 1 and HTTPS requests go to server 2.
But, you could also have only one Tomcat instance (or N identical instances) configured to handle both HTTP and HTTPS, and ensure the secure access with standard (...<transport-guarantee>CONFIDENTIAL</transport-guarantee>... in web.xml) or framework-specific configuration.
Not sure if I'm getting the gist of what you want but you could have the "pop-up" be a page served from the secure application to a protected URL. That would cause the authentication to occur at the secure server and you could go from there. For example, if the unsecured product page is on www.domain.com/browse/id1, then the "buy" button would open a pop-up to secure.domain.com/buy/id1, causing the authentication while transmitting the product id on the URL.
I work on a task that involves moving/traversing from one application to another. The applications are in separate JVMs.
While traversing to the other application, I keep track of the session ID. However, as I traverse back and forth, a new session gets created. Is there any way for me to get back the same session, using the sessionId that I retain, when I navigate back into my parent application from a child application?
Environment: J2EE with WebSphere.
As mentioned by Mork0075, the sessionID is tied to the cookie name and the server domain. If you're using the same server domain for two apps on separate JVMs, I see two options to maintain the session when switching between applications:
The long shot:
1) If you're using a database for session replication purposes, you can use the same database for both applications, and the sessionID will be available for both apps. The one problem I see here is that the objects in the session may not be available on both sides, since the code would be different etc. They'd probably clobber the other side's session objects unless you maintained the code and such on both sides so the objects were available.
The likely possibility:
2) Use different cookie names for the session on one of the two apps. By default, sessions use JSESSIONID as the cookie, and when you switch to the second app, it tries to look up a session based on that cookiename and can't find it. So, it creates a new sessionID and sends it back to the browser, thus causing your sessionID to change and not be available when you switch back to the original app. However, if you change the second app's sessionID to something else (say, JSESSIONID2) your browser would end up with two valid sessionIDs that would each be valid on their correct application. You can change the name via the administration console under the application server's Session Management->Enable cookies page.
I'am not sure if this helps, but in a ONE application scenario, you would submit a sessionID with every reponse, save it in the URL, a cookie or as a hidden field. By submitting a new request to the server, the sessionID is also submitted, to resolve it at server side. In my understand switching from one application to another means, that you have to give the sessionID with the user, across the applications. If you save the sessionID in a cookie, this perhaps is not possible, because the cookie is restricted to a certain server domain. So ensure that the session is still valid and the sessionID is present after returning to the application started.
You shouldn't have to do this manually. Most app servers support Single Sign On (SSO) so that you can log in to one application and have access to all the applications in the same SSO domain. The app server will keep track of session ids and link them to an HTTPSession object specific to the web app.
See http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/topic/com.ibm.websphere.base.doc/info/aes/ae/csec_sso.html