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
Related
I need to implement simple servlet user authentication (in Java Dynamic Web Project) but there are things that confuse me quite a bit.
Firstly, the servlet for some reason creates the cookie JSESSIONID although I never ask it to. And moreover, I cannot change its value, if I do request.addCookie(new Cookie("JSESSIONID", session.getId())), it makes something like this:
Cookie: JSESSIONID=6B5B441038414B4381EDB7470018F90E; JSESSIONID=7890D45DF445635C49BDEB3CADA8AD99; .......
so, it duplicates the cookie.
Secondly, I'm not sure where to compare cookie and session's id, and where and how to create session correctly (i.e. request.getSession(true? / false? / nothing?);)
I've read some documentation but still need help.
I have the servlet HomeServlet which shoud redirect user to authentication page if the user is not authenticated.
Here's how I do that (HomeServlet.java):
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(request.getSession().getAttribute("user") != null) {
request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
} else {
response.sendRedirect("authentication");
}
}
And I also have AuthServlet which serves jsp page with authentication forms and validates users.
AuthServlet.java:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("ACTION");
if ("login".equals(action)) {
String[] result = doSomeValidations();
if (result.size() > 0) { // show validation errors
request.setAttribute("errorLoginMessage", result);
request.setAttribute("email", email);
doGet(request, response);
} else { // authenticate user
request.getSession().setAttribute("user", userObject);
request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
}
} else if ("signup".equals(action)) {
// ...........................
} else {
doGet(request, response);
}
}
So, could you help me with understanding that? How do I implement user authentication and keep the user logged in throughout the session?
Firstly, the servlet for some reason creates the cookie JSESSIONID
although I never ask it to
HttpSession jsession = request.getSession();
you are requesting a session here and JSESSIONID cookie is created by the container in response
how to create session correctly request.getSession(true? / false? / nothing?);
request.getSession() and request.getSession(true) are exactly the same they start a new session if needed ,but request.getSession(false) means if there is already a session use it but if there isn't don't start one.
How and where you want to start the session is dependent entirely on your requirements
response.addCookie(new Cookie("JSESSIONID", jsession.getId()));
you are not suppossed to add a JSESSIONID cookie yourself , the container will do it for you .
Also you should create session once in your app , once the JSESSIONID cookie is stored in the user's browser(provided cookies are enabled) ,it will be sent along with the request.
How do I implement user authentication
Highly subjective and depends on requirements , you can read this https://docs.oracle.com/cd/E19226-01/820-7627/bncby/index.html
keep the user logged in throughout the session
Your session cookies will help you with that once the user has been authenticated ,as an example login to facebook and keep your cookies tab open
How can I save to the session a variable at the very start of the application?
The below code isn't executed when I fist run the application..
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(true);
session.setAttribute("flag", true);
//etc...
}
That code wont be executed at server startup, because there is no request and therefore no session at this time. This method belongs to a servlet, which is invoked once some client hits the url mapped to it.
If you need to do something at application startup use a ServletContextListener. If you have to store some variable for "global" use in your webapp use the ServletContext. If you really have to store it to the session use an HttpSessionListener.
I'm developing Java Servlets. At the point of checking whether a user is logged in, I want to check if the HTTP request has a valid session. For checking that, I have 2 possibilities:
(1)
protected void processRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession(false);
if (session != null) {
// user is logged in
...
}
}
Since I pass false as an argument, there is no new session created if there is no valid session existing already, and the function returns null, for what I can check.
Or I do:
(2)
if (request.isRequestedSessionIdValid()) {
// user is logged in
...
}
Is there any difference, any advantage/disadvantage? Or do both functions do more or less the same?
Form Javadoc
isRequestedSessionIdValid
boolean isRequestedSessionIdValid()
Checks whether the requested session ID is still valid.
If the client did not specify any session ID, this method returns false.
Returns:
true if this request has an id for a valid session in the current session context; false otherwise
So in sense both are same. But what you need to be aware of is request.getSession(false) will be null only in case of first request to the container. After the first request container creates a session and sends Jsessionid cookie along with response , so that it can track subsequent requests from the same browser. So in your case instead of checking if session is null or not, you should store a session attribute "is_logged_in"=true and check for this attribute as well if session is not null.
Based on the wording of the JavaDoc, it seems like there would be a distinction: if a valid session has already been created (from a prior call to request.getSession(true)), then the requested session ID will not be valid, but request.getSession(false) will have a valid (non-null) session to return. I haven't tested this theory.
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";
}
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.