I have been building a Web Application, So far I have implemented Login & Registration. User can register and then can login within the web application. Everything is working fine. What I am doing is When user clicks on Login button, a servlet is being invoked where I'm checking if the credentials are correct, If validated then Saving isLoggedIn in HttpSession and redirecting it to Home Page.
LoginServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
boolean isValidated = false;
... // Service Layer is invoked here and checks for user validation
// Assume isValidated to be true
if(isValidated){
HttpSession session = request.getSession();
session.setAttribute("isLoggedIn", Boolean.valueOf(true));
...
// redirected to /home
}else{
// redirected to /login?invalid
}
}
HomeController.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
HttpSession session = request.getSession();
Boolean isLoggedIn = (Boolean) session.getAttribute("isLoggedIn");
if(isLoggedIn != null && isLoggedIn){
...
// Service Layer is invoked to fetch `Home Page Data`
}else{
// redirected to /login?expired
}
}
All of a sudden I have encountered a strange problem, If i disable cookies for localhost using FireBug I am not able to login anymore. No matter if I enter correct username or password each time I am being redirected to /login?expired.
I don't get it, Cookies are ment to be stored at client side and Session are stored at Server side, then Why session attribute can not be set if Cookies are disabled.
I have tried disabling Cookies for already built Web Application in Spring-MVC which is in production and having same issue there as well.
When cookies are enabled, the session is stored in a cookie under the name JSESSIONID.
If cookies are disabled, the container should rewrite the session id as a GET parameter (i.e. &JSESSIONID=1223456fds at the end of all URLs).
If the URL rewriting isn't on by default, see your container's documentation on how to enable it.
You might want to consider modern frameworks (for example Spring MVC with Thymeleaf) which will automate this for you. Otherwise you need to make sure you're rewriting URLs with response.encodeURL() as Ouney directs in his answer.
A session is to maintain a stateful conversation between server and client.
By default Http is a stateless protocol.
So, to make it a stateful conversation we need to store some values on browser side (cookies) which are sent by the browser to the server with the request.
Without cookies every request is a new request and it becomes a stateless conversation.
That is the reason people use add session information in url's (jsessionId) when cookies are disabled.
To use URL rewriting use response.encodeURL() on your URLs.
with every request and response session id stored on client side as a Cookie is checked by server, if it is present the server update the information and if not a new session is created. so when you disable cookie in you browser, with every request a new session is created as cookie is disabled.
for further information you can refer this link.
click here
When we manage the session using the HttpSession mechanism that time a jsessionid save in the browser's cookies. So when you delete a cookies from the browser or disable cookies that time that jsessionid information is not sent to the server and that time server treat this request from a new session.
Related
This question already has answers here:
How do servlets work? Instantiation, sessions, shared variables and multithreading
(8 answers)
Closed 7 years ago.
This is a pretty remedial question. I have not used the HttpSession class before. I am reading this tutorial, and I see that the session is a property of the HttpServletRequest.
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// get current session, or initialise one if none
HttpSession sess = req.getSession(true);
}
My question is, how does the session get stored? On the client? In the past I have been accustomed to storing the session server / database side. How does this work? If I update the session on a given request, will that always be reflected through subsequent calls? Is the session stored on the client?
how does the session get stored? On the client? In the past I have
been accustomed to storing the session server / database side. How
does this work?
A session can be defined as a server-side storage of information that is desired to persist throughout the user's interaction with the web site or web application.
Is the session stored on the client?
Instead of storing large and constantly changing information via cookies in the user's browser, only a unique identifier is stored on the client side (called a "session id"). This session id is passed to the web server every time the browser makes an HTTP request (ie a page link or AJAX request). The web application pairs this session id with it's internal database and retrieves the stored variables for use by the requested page.
when ever getSession() method is called it returns session if exists else it create a new session.apart from creating a session it does 5 things which you wont do.
You don’t make the new HttpSession object yourself.
You don’t
generate the unique session ID. You don’t make the new Cookie
object.
You don’t associate the session ID with the cookie. You don’t set
the Cookie into the response
All the cookie work happens behind the scenes.
If I update the session on a given request, will that
always be reflected through subsequent calls?
yes it effects the subsequent calls.
With a session cookie, or if cookies are disabled you're able to see the telltale JSESSIONID parameter. This was at least the case a while ago, and I shouldn't think it has changed.
The HttpSession is by default stored in memory and created/maintained by the web server (jetty, tomcat, ...). Depending on the web server you use you might have options like storing session information into the database.
Here is the tomcat documentation for the session manager[1]
[1] https://tomcat.apache.org/tomcat-7.0-doc/config/manager.html
I am using sessions and have enabled sessions in my GAE app
<sessions-enabled>true</sessions-enabled>
<async-session-persistence enabled="true" />
I am using sessions for the purpose of a simple user login. Locally, this works just fine, my session is maintained until I logout and all my pages that are "protected" are viewable with a valid session.
The problem with my live/production server on appspot is that it doesn't work at all. When I login and authenticate, I redirect to another page. This page checks if I have a valid session (using standard HttpSession) and somehow this fails and then redirects me back to the login screen.
Does anyone have any idea why it doesn't work in the GAE production environment but works just fine locally?
Here is the code I use to check validity of current session:
public static boolean isValidSession(HttpServletRequest request) {
return (request.isRequestedSessionIdValid());
}
Update:
I'm creating session ID like this:
public static void createNewSession(HttpServletRequest request, final String username) {
HttpSession session = request.getSession(true);
session.setAttribute("username", username);
}
There is no difference between handling sessions locally and in production as such on Google App Engine. They work the same in both the environment. The only difference that I can think of is that when you create sessions (say at or after Login) locally and you set some attribute in the session say the access level of the user, it will not change even when attribute's value change(say if it is pulled dynamically from some database where it got changed after Login) until you close the tab and Login again, however in production if the attribute changes in the database and then if you refresh the page it will take the new value from the database. Well that's in my experience. Hope it helps.
I am developing a single page web application. I have included a java filter to intercept the html page request. So in this filter I am creating a session using request.getSession().
And then I am setting the JSESSIONID cookie explicitly as I have to set the HttpOnly flag in the response header Set-Cookie to prevent the XSS attack through document.cookie on client side.
Now after login I need the session, so I am accessing the session using request.getSession(). And according to the HttpServletRequest javadoc HttpServletRequest javadoc
request.getSession() returns the current session associated with this request, or if the request does not have a session, creates one.
But I am getting a different session after login.
I will retrun same session if your requesting the application with same browser, if in case if your requesting from another browser it will return new session.
I am using servlets for the first time but I made a lot of progress. My servlets are working well. So I decided to put an authentication mechanism, which creates a session, if users give the right password and id's. But sessions are totally new for me. So I don't quite follow the logic but I have started to understand.
As I mentioned before one of my servlets is dedicated for logging in. If password is correct a session is created (I don't store any object/data in sessions) and client (remoteUser) is notified that the password is accepted and session is created. What client does is to reach any other servlet in the same application. Other servlets get the session to check if it is created and valid (not timed out). For that purpose in those other servlets I get the session with:
HttpSession session = req.getSession(false); //false because this is not the place to create a session. sessions should only be created in the login servlet.
But this returns a null. So I have tried:
HttpSession session = req.getSession();
And checked with session.isNew(); and I it was a new session. So the session I have created in login servlet can't be called with req.getSession(); in another servlet.
PS: When session is created in login servlet: session.setMaxInactiveInterval(300); //5 minutes
Thanks a lot for any response!
When using Google App Engine, you have to specifically enable session support. See http://code.google.com/appengine/docs/java/config/appconfig.html#Enabling_Sessions.
I'm looking for a method or current API that allows you to add on tokens to web app requests.
Maybe within the session but not persisted.
Or if you could help me by outlining an efficient method for doing this
E.g.
1. GET request => Servlet generates a token and prints it in the view
2. returns a view with a hidden token
<input type="hidden" name="token" value="UA37jdjs9UDJS3">
<input type="submit" name="deleteEmail" value="Delete">
3. POST request => form is submitted and checks if the token is the same.
Few things to note, If there are Ajax requests then some other tokens would have to be alive for a number of requests.
If the user decides to close the browser, the token would have to die when the session
is timed-out.
If the user fails to complete the form, goes off to do something else on the site,
those tokens would have to be deleted as they go unused.
But what is the best way of implementing a system like this,
Does Spring Security 3 have a system that i can use?
within the Java,Grails,Spring MVC, Spring Security 3 and Hibernate area
Have a look at the HDIV project at http://www.hdiv.org/. They do exactly this. Even if you don't use the HDIV project's code then the information there may give you an option how to do it yourself. It was a good primer for me to learn about handling tokens for things like CSRF and other uses like double submit controls.
Did you take a look at "Synchronizer Token Pattern" in the Grails documentation at http://grails.org/doc/1.2.0/guide/single.html ?
First thought was that you might just use the already generated session id. But if you are trying to fork state I would suggest to use something like seams conversation model
Why don't just uses the session_id that the Web container generates for you when you call request.getSession()?
If you want to create your own "token" you might want to check Cookies.
A Cookie is a key-value pair sent as an HTTP header by a web server to a web browser and then sent back unchanged by the browser each time it accesses that server.
To create a cookie in a Servlet you can uses:
public void doGet ( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
// Create a cookie
Cookie c1 = new Cookie("yourdomain.token","the value");
response.addCookie(c1);
//build your response
}
The cookie will be automatically included in the next http request. You can read it back with:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
//build your response
}
I recently encountered a use case for this.
If an old application window was present in the browser, and a login link was clicked from another browser window, the login action first created a new session, and then redirected to the application window. This triggered the old window's onunload method method, which resulted in a logout request to the server logging out the new user.
Relying on a javascript onunload event for logging out seems kind of crappy to me, but this could not be changed, so we chose to do as the OP suggested and added a token in each rendered view, checking it for each request. This stops the onunload logout request from terminating the new session.
As to the best way, I would say this is pretty straightforward. You can for instance use http://java.sun.com/j2se/1.5.0/docs/api/java/util/UUID.html to generate unique keys. If you are using a component-based framework like Tapestry, JSF or Wicket there might be a more high-level way of handling this.
Is this similar to your usecase? Or are you trying to achieve something completely different?