When user access a website for the first time, the initial server response may include a SET-Cookie header to set the session ID. Such as:
Set-Cookie: JSESSIONID=04427E42C4AE7A5DD1CCE86B8B5F7110; Path=/TestSite/; HttpOnly
Then client will carry it in cookie header for subsequent HTTP requests: Such as:
Cookie: JSESSIONID=04427E42C4AE7A5DD1CCE86B8B5F7110
My question is:
So the real session object is some data structure created and maintained on server. Server just send its index key to client. When subsequent requests come, server will use that key to find session data store on server. And if necessary, server can use database to store the session data. Is this mind picture correct?
The following Java code is actually manipulating the session data which is stored on server. Though it looks like it is manipulating the request object. Right?
request.getSession().setAttribute("accountId", user.getId());
The following code is essentially key (sessionid) looking up process. It looks for a session object on server by looking up for a session id cookie sent from client. Right?
Session s = (String) request.getSession();
Is there any chance server doesn't send the Set-Cookie header? Or is it mandatory?
It seems some key-value store like Redis is very suitable for session store. Has anyone tried that?
So the real session object is some data structure created and maintained on server.
With a servlet session, yes. But in general, you could also store "real data" in the session cookie itself. Has the downside that the user can see it and mess with it, and that it can only be quite small, but has the advantage that the server does not have to store the state (and share it with others in a cluster).
The following Java code is actually manipulating the session data which is stored on server
That's right. The Servlet API provides for this interface through the request, because that way it is associated to the session key (and the individual user).
Is there any chance server doesn't send the Set-Cookie header? Or is it mandatory?
You could turn that off. If you need sessions, but don't want cookies, it gets a bit complicated. You could attach a query parameter to every URL.
It seems some key-value store like Redis is very suitable for session store. Has anyone tried that?
Yes, that's a common setup.
The default setup for servlet containers is to store the session in memory. This does not need any configuration or preparation, but works well only for single-server deployments. If you have more than one server, you need to either share the session information (using something like Redis), or have "sticky session" (configure the network to always send the same user to the same server).
Related
Intro
The users of our web application must log in in order to use the app. Communication uses (along the XMLHttpRequest) the WebSocket API.
The questions
Is storing the user name + password in a <input type="hidden"> of a <form> and then sending their data values to a login script sufficiently safe? If not, what could we do here?
Is it possible to store an arbitrary object (say, class User {...}) in the WebSocket's Session such that I can type in the login script:
session.setAttribute("web_app_user", user)
user = (User) session.getAttribute("web_app_user")
such that it is not possible to hack the web app in any way?
Generally speaking, as long as you are using WSS protocol (as opposed to WS), you are communicating with the server in a secure and encrypted manner. That said, there are a lot of different methods to further ensure safety.
I think a fairly acceptable method is sending username and password once, along with some kind of session ID that is unique to the client. If the credentials are verified acceptable by the server, just the session ID can be passed along with further calls to the server. This cuts down on the amount of times you expose a user's password.
You may want to further secure your credential verification method with some kind of cryptography algorithm such as SALT.
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?
I have a legacy Java 1.6 running localhost with Tomcat 7 application using JSP pages, a frameset with frames, javascript, but no framework like Struts. I pass an object to display in the page from the servlet using the request or session and that works fine.
However, I made some changes recently and now I can't retrieve that same object back from the session or request. It had been working fine previously, so I'm not sure what is broken, but I can't even send a string value back from the JSP's back to the servlet.
I created a new stripped down JSP and I can't get anything back from that either using the request or session. It does the same thing when I push the code our Tomcat 6 web server. Using the debugger, I see the objects populated in the session, but then lost later when a new session is created each time as in using this simple code to get the sessionid:
System.out.println("The session id is: " + session.getId());
The session id is: EB431C19B41957B2BB2EFC3DBAF32241
The session id is: C9CBD30E84D5C93DF6114C1412AE5523
I then see this in firebug under the Header, response headers:
Set-Cookie JSESSIONID=C9CBD30E84D5C93DF6114C1412AE5523; Path=/Name omitted here/; HttpOnly,
so I know cookies are set. I also removed jquery and I"m stripping down the jsp code as much as possible, but that doesn't seem to be the issue.
I'm using:
HttpSession session = request.getSession(true); but using false didn't matter.
session.setAttribute("ObjNameList", objNameList);
The context.xml has cookies set to true and we do use response.sendRedirect, but only if an error is thrown as in: response.sendRedirect("Error.jsp"); There is no place in the code with session invalidate either.
All I'm doing from the jsp is sending a form back using something like:
document.formName.submit(); which works fine. Using this code to try and set a simple string in the session doesn't work either:
session.setAttribute("somevalue","someValue");
Gives me null in the servlet here:
String val = (String) session.getAttribute("somevalue");
Any ideas as to what could be causing this?
Resultion:
It turned out to be an issue with the url, a typo actually, as BalusC mentioned, so the path for the session cookies didn't match between the jsp and the servlet.
Doublecheck if the request URL to that servlet matches the session cookie domain and path. If it doesn't match, then the browser simply won't send the session cookie back along with the request and the server will think that there's no means of an established session and will therefore simply create a new one.
You can check cookies in the HTTP traffic monitor of browser's web developer toolset (press F12 in Chrome/Firefox23+/IE9+ and open "Network" tab). When a new session starts, the server must have returned a response with Set-Cookie header with therein the cookie value and path (and implicitly domain). When the browser sends a subsequent request on the same domain and path, then it must have passed that cookie back via Cookie request header.
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
I'm new to Java. I'm writing an application to link to a vendors Flash site. I have my BlazeDs based program talking to their site. I'm running into a problem where a session cookie is not getting set. The problem is that the host doesn't return it as a "set-cookie" header.
Their site returns the following cookieDirectives to set the SMSESSION cookie
cookieDirectives
Externalized Object
flex.messaging.io.ArrayCollection
[0] String SMSESSION={CONTENT STRIPPED FOR CLARITY}; max-age=-1;path=/; domain=.-----.com
I can set the cookie in my amfConnection as follows:
amfConnection.addHttpRequestHeader("Cookie", resultString);
However, that only gives me the one cookie and there are several others I need. The others have been set earlier by the host and are set using a "Set-Cookie" header.
How can I either add this cookie to the existing ones or recover the existing cookies so I can manually add them.
I was able to resolve this by changing my approach. Instead of relying on my amfConnection to handle the cookies I grab the session id using httpclient, store it in a variable, and then push my cookies to amfConnection.
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.