I read that to persist session in servlet a cookie gets saved at client side with the name of JSESSIONID.I checked it also and I found the cookie of localhost with the name of JSESSIONID with some random String value.
So I tried to create the session manually by creating the JSESSIONID cookie in the servlet but when I am trying to get the session it's not working.
What is happening here?
Is there anything else other than cookie(JSESSIONID) that gets stored soomewhere for the session creation? If not why I'm not able to get the session ?
Please Help.
Code that I used to create the cookie and get the session
package sessionHandling;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
#WebServlet("/sessionhandling")
public class SessionHandling extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletOutputStream out = response.getOutputStream();
out.print("Hello Mr.! How are you?");
HttpSession session = request.getSession(false);
if(session != null){
out.println("You are logged in.");
out.println("session found with "+session.getId());
out.println("session found with "+session.getLastAccessedTime());
}else{
//session = request.getSession(true);
Cookie JSESSIONID = new Cookie("JSESSIONID", "12345");
JSESSIONID.setMaxAge(-1);
response.addCookie(JSESSIONID);
System.out.println("Cookie Created");
out.print("You are not logged in");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
You're not responsible for creating or tracking the cookie. The servlet container looks after this for you.
As soon as you invoke:
HttpSession session = request.getSession(true);
or
HttpSession session = request.getSession();
then the servlet container will start maintaining the session for you (and generate the cookie as needed).
The HttpSession object is maintained in server memory between requests and is usually looked up by the session id. If you create the cookie yourself the server will not know anything about it or any associated HttpSession.
Once you run your code , first time , session will be null and you will instruct the browser (or any other client) to create the JESSIONID cookie. Till here it is all correct.
Now, when you make the request again, browser (or any other client) will attach the cookie to the request and tomcat (or any other servlet engine) will receive the JESSIONID. Till here it is all fine.
But what now ? Tomcat (or any other servlet engine) will then search if it has any HttpSession object having sessionID "12345". Do you think it will be found ? No.
Why ? The code that you wrote above was only to Set cookie header in response message. It did not instructed tomcat(or any other servlet engine) to view this JSESSIONID named cookie as a session Id and create a corresponding HttpSession Object internally in Java Heap.
That's why we use request.getSession(). It instructs tomcat to do 2 things -
Whatever you did i.e. add the Set Cookie info in response by name JSESSIONID with a random ID.
Creates a corresponding HttpSession object and save it in memory (by default), so that next time when request comes, it can recognise that JESSIONID as a valid session ID by finding a corresponding HttpSession object. This was missed by your code.
Related
I have a webservice that does quite simple a forward to another webapp located on the same Tomcat container.
private Response forward(
#Context ServletContext context,
#Context HttpServletRequest request,
#Context HttpServletResponse response){
ServletContext ctx = context.getContext("/myothewebapp");
RequestDispatcher dispatcher=ctx.getRequestDispatcher("/test");
dispatcher.forward(request, response);
return Response.ok("").build();
}
This works as desired except the fact, that the sessions of this webapp are not being expired. In the tomcat manager you can see, that the opened sessions get accumulated quite fast, up to several hundreds of them.
I am not sure why they last when the response is already sent.
Any ideas what is missing in my forward-method?
Why they last when the response is already sent.
Why you think that session will be invalidated after response will be sent.
It will only be invalidated if session timeout occurs or you forcefully invalidate the session using :
Session#invalidate() method
I have a JSP, Servlet, Hibernate application. In this application I have a very weird problem. That is, if the session got expired (in other words "time out") and when the user click on a link the page will be redirected to the index page, but after that the user is not able to log in and access the last link he clicked. I will describe it step by step in below.
User log into the application. Session get created.
He access the path /Passport
User is now idle, session get expired.
User come back and click on link to access /Visa . Since the session is now idle, user will be redirected to index page.
User log in.
Click on the link to access /Visa (from anywhere where the link is available)
. The link is an where it links to its path like
Visa?idEmployee=1
Now the problem. User is redirected back to index page.
I have Filter to monitor whether the session is null and whether the required session attributes are not null. If the request do not fulfill the mentioned 2 conditions, the request will be sent back to the index.
The filter code is below.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
*
* #author user
*/
public class AuthenticationFilter_Level1 implements Filter
{
#Override
public void init(FilterConfig filterConfig) throws ServletException
{
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
HttpSession session = request.getSession(false);
Integer attribute = null;
if(session!=null && session.getAttribute("idSubUser")!=null)
{
chain.doFilter(req, res);
}
else
{
//response.sendRedirect("index.html");
RequestDispatcher dispatch = request.getRequestDispatcher("index.html");
dispatch.forward(req, res);
}
}
#Override
public void destroy()
{
}
}
In web.xml, I have added the filter from servlet to servlet, like below.
<filter-mapping>
<filter-name>AuthenticationFilter_Level1</filter-name>
<url-pattern>/RegSrvlt</url-pattern>
<url-pattern>/AdminPopulateSrvlt</url-pattern>
<url-pattern>/AgentPopulate</url-pattern>
......
Filter session timeout is configured as below.
<session-config>
<session-timeout>
1
</session-timeout>
</session-config>
So, what is happening here?
Update
When the above error happens, the URL actually looks like http://localhost:8080/xxx/Visa?idEmployee=1 even though it is redirected!
UPDATE
I found this has no connection with the filter. Then what can make this?
else
{
if (session != null) {
session.invalidate();
}
...
And check the where sessions are created (i.e. public JSPs/servlets).
Another possible cause could be a problem of caching in browser :
client browser asks for /Visa
server sends index.html => browser caches it as it is a nice html page
...
on same browser session, user clicks on a /Visa links
without even asking anything to server, browser displays cached index.html page
How do confirm :
server side, by looking the server logs to see if the page was actually requested
client or server side by using a network spy such as wireshark and look if a request is sended
client side by emptying the cache and not the cookies
How to fix :
try to add a header asking not to cache the page before forwarding to index.html - it should be possible but I do not exactly know the proper header configuration
replace the forward to index.html with a redirection. That way the browser should not cache index.html for the /Visa URL
I'm having a JavaEE Website running on a cloud-platform.
Now I want to use two types of authentications:
Is from an SSO-System, which is well integrated in the platfrom and works very nicely.
Is the problematic part: I want to authorize a user from 1) for the time of a session, and give him access to a more restricted resource.
Some details
I get the user and his data from 1).
The user first has to ask for permission to 2), which can be denyed or granted. A user gets authorization from a service, which is outside of the scope of his servlet.
For this purpose I pass a User-POJO (with the session of this user as a member) to a service.
If the service grants the rights to this user, it will set an attribute to the user session:
userSession.setAttribute("auth", "granted");
To restrict access to that resource I use a Filter:
#WebFilter("/supersecret/*")
public class NiceFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession session = req.getSession();
// check
if (session.getAttribute("auth") != "granted")
// redirect to login
else
chain.doFilter(req, res);
}
//...
While this is currently working, I feel that my solution is very sloppy.
Altering the user-session outside the scope of a servlet seems to be bad practice.
Adding an attribute to the session for security-purposes is probably not a good idea?
I'd rather want to use standard JavaEE-mechanisms, but most of them are already used for auth-method 1), like declaring login-config in the web.xml.
Any ideas for a more robust solution to this problem?
Thanks in advance :)
I’m working on a grails web application with spring security. I have a requirement for forcing a session expiration after a fixed set of time even if the session is active.
I think I can add filter and check for each request's last login time:
if (CURRENT_TIME - LAST_LOGIN > ABSOLUTE_SESSIO EXPIRATION) then FORCE LOGOUT
But the problem is that the session is still active on the server until the user makes request.
Is this possible to destroy session immediately after N minutes even if user is using the system?
I was researching tomcat session management and how spring security handles it, but didn’t find any useful information.
Could anybody point me at some example? Has anybody implemented something similar?
[Edit: An idea for killing the session at a specific time decided by the login time would be use a task scheduler like Quartz to schedule a task that is passed the session as a parameter. You could then schedule it to call a job that performs a session.invalidate() at a specific point in time. The task would be scheduled at login time.]
This is how I would do it, but it doesn't kill the session at the specific time you want. It relies on the user making a request. It's not fool proof, but you could make the application poll the site every minute or so via an AJAX call perhaps.
Set a session activation time on the users session. Then add a filter to the web application for all incoming requests that checks the (activation period + the allowed time) exceeds the current time. If it does not, then call session.invalidate();
i.e. on login
HttpSession session = request.getSession();
session.setAttribute( "activation-time", System.currentTimeMillis() );
Then add a filter to web.xml
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>com.something.SessionFilter</filter-class>
<init-param>
<param-name>max-period</param-name>
<param-value>60000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The filter would be something along the lines of...
package com.something;
import java.io.IOException;
import java.util.Date;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class SessionFilter implements Filter {
private long maxPeriod;
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpSession session = request.getSession( false );
if ( session != null ) {
long activated = (long) session.getAttribute( "activation-time" );
if ( System.currentTimeMillis() > ( activated + maxPeriod ) ) {
session.invalidate();
}
}
chain.doFilter(req, res);
}
public void init(FilterConfig config) throws ServletException {
//Get init parameter
if ( config.getInitParameter("max-period") == null ) {
throw new IllegalStateException( "max-period must be provided" );
}
maxPeriod = new Long( config.getInitParameter("max-period") );
}
public void destroy() {
//add code to release any resource
}
}
If you need to invoke something when the session is invalidated then you can write a HttpSessionListener and configure in web.xml also.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Prevent user from going back to the previous secured page after logout
I was wondering how to invalidate session in JSP and servlets. In my website a person when logs-out reaches the login page but on clicking back button he can access the previous page. I am not able to understand where to put session.invalidate()
And further where should i invalidate it, on login.jsp or my other web pages when a person hits logout.
My filter class:-
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.annotation.WebFilter;
public class LoginFilter implements Filter{
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("currentSessionUser") == null) {
response.sendRedirect("Loginpage.jsp"); // No logged-in user found, so redirect to login page.
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0);
} else {
chain.doFilter(req, res); // Logged-in user found, so just continue request.
}
}
}
In web.xml i've written :-
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/ARMS/*</url-pattern>
</filter-mapping>
On my Loginpage.jsp i've just written
<%
session.invalidate();
%>
Is it okay? Secondly I am not clear on directory structure. I am putting screen shots of it..
I am using apache tomcat 5.5 server, so i guess I should not put url-pattern annotation in filter class right? because it is only supported in tomcat 7 and above.
Invalidate the session in the servlet or the JSP that you go to when a user hits "log out".
In a crude way, you can check if a session exists on each page that a user goes.
Take a look at this thread, it has some answers that you are looking for.
http://forums.devx.com/showthread.php?t=146975
I use a servlet for the sole purpose of log outs. When a user hits the log out button it directs them to that page, which in turn checks for an active session and if it finds one, calls session.invalidate() then redirects the user back to the home page (or wherever you would like).
HttpSession session = request.getSession(false);
if(session != null){
session.invalidate();
RequestDispatcher rd = request.getRequestDispatcher("Loginpage.jsp");
rd.forward(request, response);
} else {
//There is no session. Redirect somewhere
}
This is just a quick example.