GWT Authentication and user info access - java

Just wondering if my following authentication method is correct or not. Is there any pitfall or anything missing? Suggestions and discussions are very welcome.
1> User provide user name and password, and send to the server by RPC. Comparing with the hashed value stored in DB.
2> Assuming the user name and password are accurate, an Auth Token is saved in session. The auth token will be checked when accessing the servlets.
3> The user id (integer) is returned to the client by RPC onSuccess. The user id is saved in a static variable on the client side.
4> Whenever the user specific information is needed, the rpc call with the user id (the static variable) will be sent to the server for database query.
Thanks

You'd better return the token to client side, and verify token instead of user id.
If user id is used, a user A is logged in, then another user can send request to server pretended to be user A. Your authentication method failed to protect data.

You don't need to send a user id to the client. The server has already all information he need's to recognize the user.
This code snippet creates a session cookie, with session.getId() you get the content of it, which you should save to recognize the user:
HttpServletRequest request = this.getThreadLocalRequest();
HttpSession session = request.getSession(true);
Then when the user calls your Server, you just read back the session id.
HttpServletRequest request = this.getThreadLocalRequest();
HttpSession session = request.getSession(false);
With session.invalidate() you can destroy the session, it's also possible to store objects in the session.
The this.getThreadLocalRequest() only works in *Impl .

you quoted
3> The user id (integer) is returned to the client by RPC onSuccess. The user id is saved in a static variable on the client side.
If a user refreshes his page, the value that is stored on the client side static field will be reset, right? in that case will the session ends? and user will be prompted for login again?

Related

Can we put authentication token in session object?

Can we put authentication token in session object?
For example:
session.setAttribute("authToken",authTokne);
In my case I have to use authToken in every request call.
In service layer i am using third party services. In each request i need to pass authentication token. Getting authentication token is also a one request. I need to do many request calls step by step. At first request i am getting token and holding it in object level. After some time i need to make another request from different location(another class/object), now token is not available here. For this one more request i need to send for token. So avoiding this every time new call for a token, Can i put this token in servlet session varaible?
In term of security reasons is it good approach?
The all session data is kept on the server, so you can put anything you want there. The browser user is associated to the session via sessionId in a cookie (looked up by container upon request). When a user connects to server, a cookie is dropped on the browser with sessionId. Upon return the browser sends this sessionId back so you can lookup the session (usually a Map) to track data associated with the user and their current session. Session cookies can be set to persist through browser closing or expire when browser closes or after a certain time.
Storing the auth token in session is fine, but you will not be able to find a session based on auth token stored in it if the browser doesn't support or doesn't store cookies. If a user has no cookies (maybe a custom app that calls URLs), you would add an auth-token to the URL so that the user only logs in once per session. In this case you would create a data store which contains session data and associate both sessionId from browser and auth token to the same data. This is how I have done mobile/web/api session data management in the past.
What problem are you trying to solve?

Using session.setAttribute in a deployed system

I have a system that is deployed with the link http://192.168.2.6:8484/DTR and upon logging in, it stores the user's info via session.setAttribute("user", user); However, when another user logs in, it overwrites the info of the first user as it again calls session.setAttribute("user", user);. So how can I really save the user's info so that more than two people can access the system at the same time?
This is what is currently happening:
I have two websites that are open.
I login in the first website (username: user1). Shows Hello, user1
I login in the second website (username: user2). Shows Hello, user2
I refresh the first website. It will now show Hello, user2
So how can I enable multiple users to access the website?
As discussed in the comments, the reason is both the users are logged in from the same browser and same system. So the JSessionId is same and hence the attributes are overriden.
Solution:Try with a different browser
You first get user attribute and set it if it's not there and session is new
user = session.getAttribute("user");
if (user == null&& session.isNew())
session.setAttribute("user", user);
Also please check if you are getting different session for different users session.getId() ... if not it might be the problem JSESSIONID cookie. The servletcontainer set a Cookie in the Set-Cookie header of the HTTP response with JSESSIONID as cookie name and the unique session ID as cookie value.

Servlet session cookie tampering and security

On the server side, after a successful logon, I execute :
HttpServletRequest request = this.getThreadLocalRequest();
HttpSession session = request.getSession();
session.setAttribute("user", subject.getUser().getId());
session.setAttribute("logged", true);
I then assume that the user is logged in. When the user navigates to a secure page in order to save or delete a record from my database, I run this code.
HttpServletRequest request = this.getThreadLocalRequest();
HttpSession session = request.getSession();
if (session.getAttribute("user")!=null && session.getAttribute("logged"))
{
//delete a record using the authority of the user.
}
My concern is that a client can tamper its browser cookie with a different user id. The database request would be initiated with a different user, skipping the login process.
Can java session identify tampering, or should I digitally sign the session by including this line
session.setAttribute("signature", hash(secretkey + subject.getUser().getId());
then verify that the signature is valid before changing the database.
if (session.getAttribute("signature").equals(hash(secretkey + session.getAttribute("user"))
{
//delete a record using the authority of the user.
}
Have you examined your cookies? Are you actually keeping the user-id in a cookie, and if yes, what for?
The server side session object can't be accessed from the client side, that would be a huge security problem.
If your code is correct, there's no reason or advantage in using a hash.

Invalidating session

When a user has an associated HttpSession object and then want to "log out" of the application you would invalidate that HttpSession which in turn would remove it from the map that the ServletContext keep of all sessions. But this only removes it on the server side, what happens on the client side? Does the user still keep keep the cookie with the session ID which now no longer has a corresponding session object on the server and keeps sending this to the webserver? And what happens when the user wants to login again after logging out?
I imagine the sessionId cookie will still be kept, but since this sessionId will not match any session object in the server's memory, it will be discarded by the server next time user tries to login again. On the server side it will be quite transparent, request.getSession() will return a new session object automatically.
I would like to add to the answer of maksimov.
Although the cookie is still present on the client side, it is possible for the server to delete the cookie also on the client side. Spring Security does that when a user logs out. Here's the code:
Cookie cookie = new Cookie(cookieName, null);
String cookiePath = //cookie's path
cookie.setPath(cookiePath);
cookie.setMaxAge(0);
response.addCookie(cookie);
The important instruction is cookie.setMaxAge(0). Setting the max age to 0 means the cookie has to be deleted. Thus, the server may ask the client to delete the cookie by sending it the same cookie with a max age of 0.

java servlet remember me option with cookies

I need to implement a simple remember me option in a java servlet with cookies, without using any advanced framework.
First, at login, I create the cookie and send it in response to the browser (client). The value to be stored in the cookie is just a simple hash from username + password.
How should I manage the incoming request from the browser, sending the cookie?
My approach is to check between registered users if there is any user that has the hash from username + password equal to the value in the cookie?
Is this approach correct?
Also, I did not understand exactly what is the mechanism of the expiration date. Does the browser delete the cookie when it is expired, it not, how do I check if the cookie is expired?
As long as you're not using HTTPS the method you suggest is highly insecure. I would suggest to generate some sort of session token (e.g. use java.util.UUID.randomUUID()) and set this as cookie and store it somewhere on the server side so you later can identify the user associated with this session id in the cookie.
This gives you the opportunity to reset a certain session cookie if you think there's some fraud happening and there's no direct relation between the user name/password and the cookie id you use. But note: this method is still vulnerable to a man-in-the-middle attack.
Concerning the expiration: yes the cookie becomes invalid and might get deleted by the browser if it is expired. But you can set the cookie to something in the year 3000, so it lives forever.

Categories

Resources