Session is getting overwritten in Java - java

I am facing a strange issue:
I have a page with an email field in it when I submit the page the control goes to a servlet where I am saving the email value in session by using
request.getSession().setAttribute("email_Value", request.getParameter("email_Value"));
Now, on the basis of this email value I lookup the database and extracts the information for this user if information found then remove the session attribute by
request.getSession().removeAttribute("email_Value");
if not then redirect the request to same page with an error message and prefilled email value which I am extracting from session using
if(null!= request.getSession().getAttribute("email_Value")){
String Email = (String)(request.getSession().getAttribute("email_Value"));
request.getSession().removeAttribute("email_Value");
}
It works fine on our deleopment, UAT environments but problem is coming only on PROD where we have load balancer.
The issue is that while coming back to the same page it change the email address field witch some different email value which I have not even entered on my machine i.e. it is accessing someone else session.
Could someone provide any pointer to resolve this issue. As this is Production issue, any help would be appreciated.
Thanks

looks like you need to use sticky-sessions. This must be configured in the apache

Http is a stateless protocol meaning, the server doesnt know to identify a client over a period of time.
When a client makes a call to the server (load balanced, say server_1 & server_2), it could reach either server_1 or server_2, assume the request reaches the server_1, now your code creates a session and adds the email to the session.
When the same client makes another call to the server, this time it hits server_2, the email which is in server_1 session is not available to server_2 and server_2 might have email from another session thats why you are seeing another email address.
Hope its clear.
Solution:
URL Rewriting
Cookies

If your application is deployed on multiple servers, chances are there that your sessions may get transferred between servers. Also, in such scenarios, if you are storing any objects in sessions, they HAVE TO implement Serializable interface. If they don't, then the data will not be persisted when the session gets migrated.
Also, it seems that the session gets interchanged with another one. Are you storing anything at Application level?
I would also advice you to look into HttpSessionActivationListener for your case.

Related

Does session.getAttribute(str) in Java get stored on the server of client?

I am reviewing some Java code where a logged in user object gets stored with the line:
session.setAttribute("user", myuser);
and later retreived using the line:
myuser = session.getAttribute("user");
This works as expected, with the session.getAttribute() being able to read the saved user. However, I am wondering if this will work if the site is behind a load balancer, and mutliple instances are spinning up and down.
Are session variables stored on the client?: in which case, I'd assume a session'ed user object would be accessible across all running instances.
Or does session.setAttribute() store the user object on the server?: in which case if a user logs in on one instance, then a few page requests later gets bumped to a different running instance, I assume the session'ed user object would not be accessible.
Could anyone shed any light on this? Where does session.setAttribute() store it's data?
This is how it usually works - after user login, server creates unique SESSION_ID and return it in cookies. Also server creates Session object to store session information (Like session start time, session last activity time, user name etc.). When next request from same user comes - it contains that SESSION_ID in cookies, so server can find appropriate Session object.

Is it possible to invalidate spring mvc sessions if browser is closed or power got off?

In Spring MVC I am able to get all the session by the following code.
int active= sessionRegistry.getAllPrincipals().size();
List<String> activeSessionsId = new ArrayList<String>();
for(int i=0;i<active;i++){
List<SessionInformation> si=
sessionRegistry.getAllSessions(sessionRegistry.getAllPrincipals().get(i), false);
for(SessionInformation s:si){
System.out.println("SessionId="+s.getSessionId());
activeSessionsId.add(s.getSessionId());
}
}
Here sessionRegistory is my spring given bean I configured it like this:
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
And autowired in my controller like this:
#Resource(name="sessionRegistry")
private SessionRegistryImpl sessionRegistry;
I thought activeSessionsId list would be contain only active session but it contain all the users session that I logged in and passed by spring security. For some users I closed the browser without logout and I was expecting this session won't be add in my activeSessionsId
list but it is not like that .
I observed all sessionId got added in activeSessionsId.
Actually Concept wise I know the session creation is happening by server side .But Please any one let me know whatever I am trying is it possible or not in a case of spring MVC.
From the point of view of server, you must admit that you cannot know if browser if closed. Ok, you can try to use javascript to send something when closing window, but anything can happen :
the network can go down at any point (system, modem, proxies), voluntarily or not
power can go off, voluntarily or not
javascript can be disabled
user can use a headless browser (Selenium, Python or Java or ... code) that could choose to ignore all or part of javascript
So use javascript if you want and it will work in the great majority of use cases, but always keep a session timeout for the unwanted silent disconnection that can still occur whatever you do.
In general, when I close the browser, the server i'm talking to will have no way of knowing I closed the browser - unless, you tell it somehow. Typically you do this with a bit of javascript and listen for the browser close event and call the server to tell them they closed the browser.
On this call, you can invalidate that user's session and that should remove it from your active sessions list
Alternatively, you you add session timeout on the server which will remove the sessions upon expiry of certain amount of time.

Keep the user input in browser without any binding to Bean

I do have a sensitive user input entered by user. When user submits the page, it will sent to second server (https) (to which sending this sensitive data is fine) through javascript form submit. After that server process some, it will be returned to main server(https) with that sensitive input.
Problem here is, I cant bind this input to beans deployed in my server (as my server is not compliance certified). So when second server posts the values back, it is getting lost as it is not bonded. It may be really bad situation, but this is what happens.
Please help. Thanks in advance.
You could put the value in session scoped variable.

Preventing Multiple Login with same login credentials

I am developing a web application that needs to prevent multiple login using the same user name and password concurrently.
If it happens on the same machine then we need to do something with the user session, but it should also prevent if they are login on different machines using the same user name and password.
What can be the best approach :-
1) should i store the user session,credentials,and IPAddress of the machine in the DB.
2) should we use the session tracking mechanism in the application itself.If so what is the best approach?
Also , We have to keep following things in mind:
1) If user close the browser without logout.
2) If session times out.
Hope it clears the question.
Besdies data base hits (which could fail if your server is broguth down without updating db) : A data base friendly way is not to hit the data base for every re login or you could get denial of service attacks that brig you dowm. Instead implement a session listener in J2EE and check if same user is logged in by looking up the user id in a cache.
If you have more than one app node then need a distributed cache with a time out same as session time out in web.xml.
Simply have a field in your database that has text that says online or offline for each user, according to whether they are logged in or not. So when someone tries to log in with that username, check the database if the field says online for that given user on submit. If the field says online, don't allow log in. Otherwise permit it.
without using a database
you can store if a user is online in a text file
$check= "onlineCheck.txt";
$fh = fopen($check, 'a') or die("can't open file");
$nowOnline= "USER678 \n";
fwrite($fh, $nowOnline);

Session management between thick client and server?

My application is a Eclipse Rich Client and I would like to add authentication and authorization features to. My Users and roles are stored in a database and my application also has a web based admin console which lets me manage users and roles. I am leveraging Spring security on this admin console.
So here's my requirement:
I would like my thick client to provide users with a login dialog box. The authentication would need to be performed on the server side (it could be a webservice) and the roles have to flow in to the thick client. I would also like to manage sessions on the server side, somehow.
I really can't think of any easy way to doing this. I know that if I were to use Spring Rich Client, it would integrate pretty well with Spring Security on the server side.
But, that is not an option for me at this point.
Please share your thoughts on how to acheive this. Appreciate your help.
Since you're leaning toward web services (it sounds like you are) I'd think about taking the user information from your rich client (I assume user ID and password), using WS-Security to send the encrypted info to a web service, and having the web service do the auth stuff. Also I'd think about the web service returning any info that you want to go back to the rich client about the user (first/last name, etc).
I developed a similar application recently using the Challenge-Response-authentication. Basically you have three methods in your webservice or on your server
getChallenge(username) : challenge
getSession(username, response) : key
getData(username, action?) : data
getChallenge returns a value (some random value or a timestamp for instance) that the client hashes with his/hers password and sends back to getSession. The server stores the username and the challenge in a map for instance.
In getSession the server calculates the same hash and compares against the response from the client. If correct, a session key is generated, stored, and sent to the client encrypted with the users password. Now every call to getData could encrypt the data with the session key, and since the client is already validated in getSession, s/he doesn't have to "login" again.
The good thing about this is that the password is never sent in plain text, and if someone is listening, since the password is hashed with a random value, the call to getSession will be hard to fake (by replaying a call for instance). Since the key from getSession is sent encrypted with the users password, a perpetrator would have to know the password to decipher it. And last, you only have to validate a user once, since the call to getData would encipher the data with the users session key and then wouldn't have to "care" anymore.
I've a similar requirement I think. In our case:
user provides username and password at login
check this against a USER table (password not in plain text btw)
if valid, we want a session to last, say, 20 minutes; we don't want to check username and password every time the thick client does a retrieve-data or store-data (we could do that, and in fact it wouldn't be the end of the world, but it's an extra DB op that's unnecessary)
In our case we have many privileges to consider, not just a boolean "has or has not got access". What I am thinking of doing is generating a globally unique session token/key (e.g. a java.util.UUID) that the thick client retains in a local ThickClientSession object of some sort.
Every time the thick client initiates an operation, e.g. calls getLatestDataFromServer(), this session key gets passed to the server.
The app server (e.g. a Java webapp running under Tomcat) is essentially stateless, except for the record of this session key. If I log in at 10am, then the app server records the session key as being valid until 10:20am. If I request data at 10:05am, the session key validity extends to 10:25am. The various privilege levels accompanying the session are held in state as well. This could be done via a simple Map collection keyed on the UUID.
As to how to make these calls: I recommend Spring HTTP Invoker. It's great. You don't need a full blown Spring Rich Client infrastructure, it can be very readily integrated into any Java client technology; I'm using Swing to do so for example. This can be combined with SSL for security purposes.
Anyway that's roughly how I plan to tackle it. Hope this is of some use!
Perhaps this will help you out:
http://prajapatinilesh.wordpress.com/2009/01/14/manually-set-php-session-timeout-php-session/
Notice especially this (for forcing garbage collection):
ini_set(’session.gc_maxlifetime’,30);
ini_set(’session.gc_probability’,1);
ini_set(’session.gc_divisor’,1);
There is also another variable called session.cookie_lifetime which you may have to alter as well.
IIRC, there are at least 2, possibly more, variables that you have to set. I can't remember for the life of me what they were, but I do remember there was more than 1.

Categories