Best way managing session in Java. I heard that cookies are not reliable option for this as they gets stored into browser and can be accessed later on? Is this correct? If possible please come up with the answers with the coding example.
Which is the best among:
URL Rewriting: Server will add an additional parameter at the end of URL link
Hidden parameter in Form: server will add an additional parameter at every form in HTML
cookie: Server will ask browser to maintain a cookie.
The session management (client identification, cookie handling, saving session scoped data and so on) is basically already done by the appserver itself. You don't need to worry about it at all. You can just set/get Java objects in the session by HttpSession#setAttribute() and #getAttribute(). Only thing what you really need to take care of is the URL rewriting for the case that the client doesn't support cookies. It will then append a jsessionid identifier to the URL. In the JSP you can use the JSTL's c:url for this. In the Servlet you can use HttpServletResponse#encodeURL() for this. This way the server can identify the client by reading the new request URL.
Your new question shall probably be "But how are cookies related to this? How does the server do it all?". Well, the answer is this: if the server receives a request from a client and the server side code (your code) is trying to get the HttpSession by HttpServletRequest#getSession() while there's no one created yet (first request in a fresh session), the server will create a new one itself. The server will generate a long, unique and hard-to-guess ID (the one which you can get by HttpSession#getId()) and set this ID as a value of the cookie with the name jsessionid. Under the hood the server uses HttpServletResponse#addCookie() for this. Finally the server will store all sessions in some kind of Map with the session ID as key and the HttpSession as value.
According to the HTTP cookie spec the client is required to send the same cookies back in the headers of the subsequent request. Under the hood the server will search for the jsessionid cookie by HttpServletRequest#getCookies() and determine its value. This way the server is able to obtain the associated HttpSession and give it back by every call on HttpServletRequest#getSession().
To the point: the only thing which is stored in the client side is the session ID (in flavor of a cookie) and the HttpSession object (including all of its attributes) is stored in the server side (in Java's memory). You don't need to worry about session management youself and you also don't need to worry about the security.
See also:
Authenticating the username, password by using filters in Java (contacting with database)
How to redirect to Login page when Session is expired in Java web application?
How to implement "Stay Logged In" when user login in to the web application
All Java web frameworks support cookies or URL-encoded session IDs. They will chose the correct approach automatically, so there is nothing you need to do. Just request the session object from your container and it will handle the details.
[EDIT] There are two options: Cookies and a special URL. There are problems with both approaches. For example, if you encode the session in an URL, people can try to pass the session on (by putting the URL into a mail, for example). If you want to understand this, read a couple of articles about security and build app servers. Otherwise: Your Java app server will do the right thing for you. Don't think about it.
The cookie just stores the session ID, this ID is useless once the session has expired.
Servlet specification defines the API for accessing/setting session data in standard J2EE application. Also it defines that session data is stored on the server-side and nothing is transferred to the client except the session identifier. There are 2 mechanisms how session id is transferred:
1) request URL e.g. jessionid=....
2) cookie
Mechanism is determined automatically based on client capabilities.
EDIT. There is no best option, there is servlet specification that defines the way.
Http is a stateless, client-side pull only protocol.
To implement a stateful conversation over it, Java EE Web Server need to hide some information (which is sessionid) in client-side and the mechanism it can use should follow HTTP and HTML spec.
There are three ways to accomplish this goal:
URL Rewriting: Server will add an additional parameter at the end of URL link.
Hidden parameter in Form: server will add an additional parameter at every form in HTML.
cookie: Server will ask browser to maintain a cookie.
Basically, modern web server will have a "filter" to choose which way to use automatically.
So if Server detected that browser already turn off cookie support, it will switch to other ways.
2 important questions:
Which web technology are you using? JSF, Struts, SpringMVC or just plain servlets/JSPs.
Servlets/JSPs already give you the session support you need. JSP Example: Hello, <%= session.getAttribute( "theName" ) %>
I really don't think you have something to worry about cookies, since the data is stored safely in the server and handeling the cookie is done automaticlly.
Is your application installed on a single server?
If YES than you have no problem, use the servlet session option.
if NO than you gotta find another way to do this. Like using a sticky session, or maybe parse the entire session object in the requests/responses as a field. This option indeed requires you to take security measures.
Related
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 implementing a game in JSP and Servlets. The game should support multiple players.
It is obvious that each player ID is generated on the server side. But where do I store it on the client side, so I can retrieve it later (from within the servlet) when the client calls for the Servlet?
Sessions are handled automatically by the servlet framework, and you retrieve the session by calling request.getSession() in a servlet.
The session is available in different ways once you start using a framework once you outgrow servlets (this happens quickly) and is framework-dependent.
Depends on how long you want the client to remember the player ID.
During the session: The session is a good place
During his subsequent visists: A (permanent) cookie is a good place
Session: request.getSession()
Cookie: request.getCookies() and response.addCookie(cookie)
Session ids are usually stored in a cookie.
I'd be amazed if JSP doesn't have a session library that would take care of all that for you.
I heard that ebay uses Java, but I didn't find jsessionid cookie when I signing in.
Are there alternative techniques exists to track users sessions?
How do you avoid using jsessionid?
There are may, many different options to achieve this. The simplest one I can think of is to store your own cookie and use memcache (or similar) to share the session data between all your servers.
With this solution, you don't have the problem of your session living on only one server.
I checked just now that ebay actually created 7 cookies out of which 4 would expire as soon as I close my browser (one or more of them may actually be for session management).
To maintain information about a user session on HTTP which is stateless, the server must give the client a unique identification which must be used in later requests to the server for identifying it as the same client. This unique identification is mostly stored as cookies, sometimes passed on and on as a request parameter or you can use any other suitable method so that the identification is not lost.
As far as I know, automatic setting of JSESSIONID can be turned off in a JSP application and our own session management method can be used.
<%# page session="false" %>
I'm writing a small webserver in Java, using HttpCore for most Http requests/responses etc.
Now I would like to be able to create, store and load cookies. I can't find anything in HttpCore and I'm not that familiar with other libraries. Is there an exisiting library (preferably with a working example) to handle cookies?
Edit: I see I was a bit confused regarding the usage of cookies. I'm not completely sure how it works, but I want to keep a session, and to access session variables from the web server. How can I do this? If the browser saves cookies, does it send them to the server? How do I access them?
Session support in a server, is typically built using an object store. A simple object store would be a Map or a Set. The objects in this store ( the values in the case of the Map) have a one-to-one mapping with the concept of a logical session, i.e. for each session created by the server, there will be one item in the store.
Sessions managed by the store may allow for attributes to be associated with them. The list of such attributes may not be known before hand, so you'll need another map for this purpose; the keys would be the attribute names, and the values would be attribute values.
As far as management of the session store is concerned, you'll need to create a new Session in the store, when an API call is made to your server. In simpler words, if a web application decides that it needs to create a session, the server's API must provide the necessary interface to do so. Creating the session object alone is not enough; you'll also need to write the session ID out as a cookie when you first create the session. The API must allow for writing the appropriate response in such a case. You might want to take a look at the Servlet API, specifically for the HttpServletRequest and HttpSession classes, and a servlet container implementation for this purpose.
On the topic of accessing cookies from a request, you'll need to parse the incoming HTTP request headers to check for any cookies sent by the browser. Browsers and other HTTP clients are expected to use the Set-Cookie request header for this purpose. You'll need to ensure that a session object may be returned to the web application only when a valid cookie is supplied in the request.
I'm using gwt on my glassfish server, and I'm attempting to make some of my RPC calls authenticated via cookies. Is this possible? Are there any examples out there of how to code it?
Depending only on the cookie for authentication will make your website/services vulnerable to Cross-Site Request Forging/XSRF/CSRF attacks - read more on that in Security for GWT Applications.
The best way would be to double check the value you get from the cookie and with the one that's been transported to the server by some other means - as part of the request (header, a custom field, etc).
Other than that, there are many tutorials covering the subject - just search for Java (servlet) authentication - it doesn't have to be GWT-specific. The Google Web Toolkit Group also has many threads about the subject.
I assume that you use GWT's RPC servlet for handling requests made by the client.
One option that comes to my mind is to write and configure a ServletFilter which can examine the cookie, before the request reaches GWT's servlet.
You might rethink using cookies as it is a potencial security hole.
Why not put your communication to HTTPS?
Can you not just use the standard 'session' scope, i.e.
request.getSession()
A pattern I use in GWT apps is to have a separate 'old fashioned' login form which sets up the session. The GWT app's host page is then displayed after they have successfully logged in.
If the necessary values aren't in the session, then the user isn't logged in. Your service should return an exception, maybe, which instructs the GWT app to redirect to the login page, or display an error.