I'm new to java web development. I have created a servlet/jsp web application that is deployed on Tomcat 7. After authentication, the user go through few page that has its own forms. The inputs are stored as session attributes and are displayed on a confirmation before log out.
For the log out, I used session.invalidate() and sendRedirect("Logout.jsp").
If I run the application again, it will return my new input, but it will also copy all the old session input.
I have disabled the session persistence and put the context cachingAllowed="false".
It seems that all the session attributes are stored in the server memory. Is this problem causes by the server configuration?
Make sure you use request.getSession(boolean b) method and not the request.getSession()
All page that should be accessible to logged in user should make a call to request.getSession(false)
If call to this method does not return any session, user should be redirected to login.
make sure your information store in session like this:
HttpSession session = request.getSession();
session.setAttribute("info", info);
when you want to remove it,you should do it like this:
HttpSession session = request.getSession();
session.removeAttribute("info");
Related
I am working on a java application using spring security.
I want to avoid the session fixation, but the session fixation solution found on the docs seem not to be working as expected... here
So, I did this on my login
final HttpSession session = request.getSession(false);
if (session != null && !session.isNew()) {
session.invalidate();
}
Works great and changes the JSESSIONID everytime I call the login page...
But once I am logged in, I can call the login page again, get another JSESSIONID and still be logged in, I can just click on the back button and come back to the logged users area.
It does change the JSESSIONID, my question is, shouldnt it have a bigger effect? like invalidate my session or log me out?
When I call the log out form it does log the user out and works as expected, I am just wondering if changing the JSESSIONID has a real effect or does nto matter.
ANy idea?
I am using security 3.2
spring's session is mapped to JSESSIONID. so if a customer would have session state beans, they would be lost after changing JSESSIONID.
even though documentation tells
Spring Security protects against this automatically by creating a new
session when a user logs in
you can explicitly set configuration for session fixation by adding this
<security:session-management session-authentication-strategy-ref="fixation" />
and defining fixation bean with SessionFixationProtectionStrategy class
I am trying to create a simple login page. I retrieve a User object from my database using hibernate. That part works fine, I'm doing that as follows:
//data from login form
String username = request.getParameter("username").trim();
String password = request.getParameter("password").trim();
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
try {
User currentUser = (User) session.get(User.class, username);
if(password.equals(currentUser.getPassword())) {
response.sendRedirect("index.jsp?page=login&success=true");
} else {
session.getTransaction().rollback();
response.sendRedirect("index.jsp?page=login&success=false");
}
} catch //...
Given the correct credentials, login is successful. If I understand correctly, my code above already stores the User in the session, if the login was successful, so all I have to do is access the session?
However I can't figure out how to access the retrieved User object from the session in other places of my website. After the user is logged in, I want to show user-specific information on my website and for that, I need to check the username and whether the user is logged in at all.
So to sum up: How can I use the retrieved User object in other parts of my website?
I just started learning Java EE and hibernate, so please bear with me.
You can do it using an HttpSession that can be retrieved by the HttpServletRequest object.
HttpSession httpSession = request.getSession();
httpSession.setAttribute("user", user);
Now to check if the user object is present in different parts of your application, you can do the following:
HttpSession httpSession = request.getSession(false);
//False because we do not want it to create a new session if it does not exist.
User user = null;
if(httpSession != null){
user = (User) httpSession.getAttribute("user");
}
if(user!=null){
// Do stuff here
}
To logout a user or in other words, to invalidate the session, you can call the invalidate method.
httpSession.invalidate();
Useful links: HttpServletRequest and HttpSession
HttpSession is different from the Hibernate session. The Hibernate session provides a way for you to query and save persistent entities that are stored in a database. The HttpSession is provided by the servlet container to give a way to
store objects for a given user based on a cookie provided in the user's request.
What you store in the HttpSession should be minimal, partly to save on overhead from nodes in the cluster reconciling their sessions but mostly to make your application less error-prone. Here it could be sufficient to store a user's ID in the session rather than the whole user object. Even if the User object contained roles it would be better to look those up for each request so that any changes get applied immediately. Also by storing only ids you avoid problems with reattaching entities (allowing you to avoid one of the more confusing and troublesome parts of using Hibernate). When something else in your application needs to access the User it can query the Hibernate session (using session.get(id)) passing in the primary key value stored in the HttpSession.
You should use a 1-way hash to store passwords so that will change how you compare passwords.
The application should create a Hibernate SessionFactory once only upon initialization, it is threadsafe and everything in the application should use that one instance.
Rolling back a transaction where all you do is select seems unnecessary.
Typically you access the HttpSession only from the view and the web controller. It looks like you have web controller logic and business logic lumped together, a division of responsibilities between controller and service may be helpful here.
Assuming you are in a Web application and you want something from the User entity, you should propagate the same value/reference to the Web/controller layer (in case you are using an MVC approach); then keep it there since it's the most appropriate place to store something via the HTTP session provided by most frameworks.
RECOMMENDATION(S)
You should not be rolling back a get/select operation?
A SessionFactory should be instantiated once.
The Session you have mentioned here(org.hibernate.Session) is cannot access from the other places of your web site instead you put your User object into a HttpSession .
Here is how you going do this:
HttpSession httpSession = request.getSession();
httpSession.setAttribute("loggedUser", your_user_object reference_here );
Here is how you access from other placess:
httpSession.getAttribute("loggedUser");//return type is Object here
Httpsession is per browser.Ideally should we reset the session variables on logout otherwise it will always be available for that Browser even user login again.Is that correct?
You can just invalidate the session by calling HttpSession.invalidate() which will clear all the attributes as well as destroy the session itself.
You don't need to reset all session variables. You just need to call session.invalidate() and servlet framework will take care of the rest.
Is HttpSession in java servlet is created only after
HttpSession s = request.getSession();
?
In my code I didn't write that, but when I use if (request.getSession(false) == null) ..., it doesn't work. Why?
A HttpSession is created when calling request.getSession().
But if you access a JSP by default it will automatically create a session.This behaviour can be disabled by using: <%# page session="false">
Are you using JSP?
Read JavaDocs, it says clearly:
This says, request.getSession()
Returns the current session associated with this request, or if the request does not have a session, creates one.
And the other variant request.getSession(isCreate)
Returns the current HttpSession associated with this request or, if there is no current session and create is true, returns a new session.
If create is false and the request has no valid HttpSession, this method returns null.
To make sure the session is properly maintained, you must call this method before the response is committed. If the container is using cookies to maintain session integrity and is asked to create a new session when the response is committed, an IllegalStateException is thrown.
Update
On a bit research, I have found that Session is not created unless request.getSession() is called somewhere. Since, The servlet container uses this interface to create a session between an HTTP client and an HTTP server. There are good chances that your Servlet container creates the Session for you by default.
refer:
Java Doc HttpSession
Discussion on JavaRaunch: is HttpSession created automatically?
But, to be safer side, use request.getSession() to get session, and use request.getSession(false) only when you need to verify if a session has already been created.
In addition to Nishant's answer note that session can be created implicitly by JSP pages unless you configured them not to create a session with <%# page session = "false" %>.
To make it complete:
session is not created, unless you call request.getSession(), in your servlet, use request.getSession(false) to get existing session without creating new session
if you use JSP page, session is automatically created for you - variable session - unless you specify <%# page session="false" %>
even if your session is created automatically, you can use session.isNew() to find out, if it has been newly created
Try to remove session cookies from browser and make another test. If it does not work then some other component is creating a new session before that call.
I've a JSP/Servlet Web App that consist of more than one servlet (and some JSPs)
I need to create an new HttpSession whenever the users access servlet A, knowing that, servlet A is the home page (i.e. he access it as the first servlet/page in the application).
So far so good, I can write the following code at the start of the servlet A:
HttpSession session = request.getSession(false);
if (session == null) {
logger.debug("starting new session...");
session = request.getSession();
// other stuff here
}
But the problem is, if the user didn't close his browser (even if he closes the tab - in Firefox for instance - the session will still be open), so when he try to open my site again, the last session will be re-used (in the range of session timeout of course), and this I don't need. I need that whenever he accesses Servlet A, he gets a brand new HttpSession.
But unfortunately, he may access this servlet twice per session based on some scenario!
It seems to me that you should not be using session for this purpose. Perhaps you can add a parameter to request (i.e. transaction id) and pass it around trough all your related requests, so when user would close page the transaction id would be gone. Then you can store any data associated with given transaction id in the http session or elsewhere and could also clean it after some time.
The spring framework has an abstraction called bean scope, which seem like a good fit for your scenario, so you can create a custom scope for your transaction (or user's session) and store all the data in some bean scoped with such custom scope.
You should store some information (attribute) in the session that it's been used. And if it has been, invalidate
HttpSession session = request.getSession();
Object isOld = session.getAttribute( "isOld" );
if ( isOld != null )
{
session.invalidate( );
// Recreate session
session = request.getSession( );
}
session.setAttribute( "isOld", new Object( ) );