i am using spring 3 (annotations) with jsf, and i know how to create a session and how to invalidate it afterwards...
so when i login and use the logout button at the end, then everthing works great. but the problem is, the session remains if i don't click at the logout button. if i now log in with a different user, then the old session data remains - cause the old session wasn't invalidated.
so how can i force the system to create a new session if the old session wasn't invalidated?
You should clear the session when the user logs in. This way, whether they've logged out or not, you're starting fresh:
#RequestMapping("login")
public String login(LoginForm form, HttpServletRequest request, HttpSession session) {
session.invalidate();
HttpSession newSession = request.getSession(); // create session
// log the user in
return "successPage";
}
Steve's answer is good. Just to add a bit more context, you should always invalidate and create a new session after a user authentication event as a best practice against session fixation attacks.
Another way to accomplish what you are looking to do is to use Spring Security. I'm not sure if you've considered it, but by default it will handle invalidating and generating new sessions upon each user login for you. Also, it has other features which you may or may not find useful. This link may be helpful: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/ns-config.html. Scroll to section "3.3.3/ Session Fixation Attack Protection" for relavent info to your question
To Create new session after logout check session.isNew() condition if session is old then call invalidate(). Redirect logout method to /login mapping. It checks session and it will creates new session when you call invalidate() method.
Logout Code:
#RequestMapping("/logout")
public String logout() {
return "redirect:/login";
}
Login Code:
#RequestMapping(value = "/login")
public String login(HttpServletRequest request, HttpSession session) {
/*
* create new session if session is not new
*/
if (!session.isNew()) {
session.invalidate();
}
return "login";
}
Related
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
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");
I am working on struts2. I use below code to check if the User have logged in or not
public String execute()
{
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession(false);
System.out.println(session);
if(session == null)
{
return "UserLoggedIn";
}
return "success";
}
When I access print the session value in console first time it print null. But when I do the same thing by refreshing the page it prints some thing like below and its ends up letting the user to access the page with out logging in.
org.apache.catalina.session.StandardSessionFacade#16f21478
How to carry out session checking to see whether user logged in or not.
Thank you very much.
Well if you are just doing this for learning purpose, i believe its better to store a variable in session, once user logged in.
Say, when use click login button and if credentials provided by user are correct you can store a variable (logged-in) in to session and on clicking log-out button can clear this variable.
However there are few more things you need to take care.
Its better to use SessionAware interface provided by Struts2 which is a clean way to inject Session as Map in you action class.
public class YouAction implements SessionAware{
private Map<String, Object> sessionMap;
#Override
public void setSession(Map<String, Object> sessionMap) {
this.sessionMap = sessionMap;
}
}
Above way let you action independent from direct dependencies from HTTP objects, which can be helpful in unit testing.
If you have the option can use Spring security which is a much better way to handle User authentication and Authorization process.
When user logged in put a variable in session.When logout clear that one from session.
Then check that variable in session .
General question about java servlets and the best way to handle requests. If I hit my doGet method from a remote server request:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
....
<do work here>
....
kill(request);
}
private void kill(HttpServletRequest request) {
//How do I kill the user session here?
}
After I process the request at my end and generate my output to the requester, I want to basically "kill" their session. Currently, that session lingers and thus eats up memory. Then once the max is reached, all other calls are timed out.
I tried creating a HttpSession object using the request object, but got the same results:
HttpSession session = request.getSession();
session.invalidate();
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
is the proper way to go as suggested by the documentation. A new session will be created once the client sends a new request.
You mentioned that your sessions still take up memory. Do you have any other references to those objects on the session?
You also might want to have a look at: Servlet Session behavior and Session.invalidate
you can remove an attribute from a session using
session.removeAttribute("attribute name");
Try with
session = request.getSession(false); // so if no session is active no session is created
if (session != null)
session.setMaxInactiveInterval(1); // so it expires immediatly
If you dont want Session behavior i.e, having state between multiple requests. Why do you want to create/use session at all. Do not create session or do not store anything in the session.
To make sure that your code is not using session, write a request wrapper which will override getSession() methods.
Set a time-out period in web.xml
The
HttpSession session = request.getSession(true);
and
HttpSession session = request.getSession();
both creates a new session if there is none present.
My problem is that i want to invalidate() the session if its allready present and then create a new one.
I that possible ..i mean is there any way out to achieve this..??
How about this?
HttpSession session = request.getSession(false); // Will not create a new session.
if(session!=null)
{
session.invalidate();
}
session = request.getSession(true);
first kill your old session
session.invalidate();
and after that reopen it with
HttpSession session = request.getSession(true);
dont work?
First do a session.invalidate(); and if necessary then do a response.sendRedirect("url"); to an url where in you can just do request.getSession(); to get a new session.
Note that this approach is not guaranteed to work in a JSP file, simply because the response is in most cases already committed (so that the container cannot set the new value of the jsessionid cookie in the response header). You really need to do this in a Servlet or Filter.
That said, why exactly do you want to invalidate the session and then immediately get a new session all in the same request? This sounds like a workaround for a certain problem for which there may be better solutions.