getSession() always creates a new session - java

We have SecurityFilter class in our application by implementing Filter and our doFilter method looks like this.
public void doFilter(ServletRequest sres, ServletResponse sreq,
FilterChain chain) throws IOException, ServletException {
LOGGER.debug(Logger.buildLogMessage("Starting SecurityFilter.doFilter"));
HttpServletRequest request = (HttpServletRequest) sres;
HttpServletResponse response = (HttpServletResponse) sreq;
HttpSession session = request.getSession();
We have the following entry in our web.xml
<filter>
<filter-name>SecurityFilter</filter-name>
<filter-class>com.a.b.c.web.filter.SecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/resources/*</url-pattern>
</filter-mapping>
We have many REST calls to our application and all of them pass through this filter. The Java API documentation says, the request.getSession() returns a session if exists else it creates a new session. But in our application the request.getSession() always creates a new session for every REST call. What could be going wrong here ?

If your application settings are set to track JSESSIONID via cookie, the application will return the same session if you're making a request from the same browser, and a new session if you're making a request from a different browser. This is obviously because cookies live on a per-browser basis.

Related

How to avoid request to Java Web Application servlet from outside some network?

I am trying to build a web application which is only meant to be accessed from inside a specific network, lets say a company's network. If anyone tries the URL for the application from outside the company's network then the access should be denied. I know I can use doFilter method for this task. But I am not really sure how to start checking the requests that are only coming from inside the company's network.
Can anyone point me to any useful resource or tell me how to achieve this in Java?
try to implement
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
String validParams = request.getParameter("validParams");
if(!"blockTheRequest".equals(validParams)){
filterChain.doFilter(request, response);
return;
}
HttpResponse httpResponse = (HttpResponse) httpResponse;
httpResponse.getWriter().write("a different response... e.g in HTML");
}
and you need do configure it with in web.xml
<filter>
<filter-name>yourFilterURL</filter-name>
<filter-class>servlets.SimpleServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>yourFilterURL</filter-name>
<url-pattern>*.pattern</url-pattern>
</filter-mapping>

New session always being created when using getSession()

This is a duplicate of this question, but that question is over 4 years old and doesn't have an accepted answer. I'll offer bounty from this question if it does not get an answer.
In my J2EE web application, I have a Filter called AlwaysCreateSessionFilter. Here is my doFilter method:
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) {
if (request instanceof HttpServletRequest) {
((HttpServletRequest) request).getSession();
}
chain.doFilter(request, response);
}
And in this war's web.xml, I have:
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
The browser always correctly includes a JSESSIONID cookie with the value from the server's most recent response (provided in the response's Set-Cookie header). But the problem is that the server always provides a brand new value for JSESSIONID in the Set-Cookie header, not the same one provided with the request. So the server is creating a new session on each request.
I have set a breakpoint in the doFilter method, and can confirm that request.getSession(false) returns a valid session with the correct id that corresponds to the value of the JSESSIONID cookie being provided with the request. It's just that, when the server responds, it always has that Set-Cookie header set to a brand new JSESSIONID, and I can't figure out what is doing it.
Here is crude diagram to illustrate what is happening:
Any help would be appreciated.

Disabling page access via cached URL or back button after logging out(Servlets)

Requirement:
I am implementing secure logout feature in my web app(Servlets-JSP based) i.e after logging out user shouldn't be able to access any pages by typing url from Cache or hitting the back button on browser,Application should redirect to login page.
What I did:
Based on some reading and some SO answers i started implementing this feature with Filters and this is what i did.
in web.xml
<filter>
<filter-name>NoCacheFilter</filter-name>
<filter-class>com.controller.NoCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>NoCacheFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
in my Filter class doFilter() method
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request=(HttpServletRequest) servletRequest;
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
HttpSession session=request.getSession(false);
if(session != null && !session.isNew()) {
chain.doFilter(request, response);
}
else {
response.sendRedirect("/WEB-INF/login.jsp");
}
}
I am using chrome,the feature is not working at all,i.e user can still access pages after logging out with URL typing or hitting back button.
Where i am doing wrong? what changes should be done to make it work.
Thanks in advance,

Getting hostname of the client that is calling my JAX-RS rest webservice

I have developed my rest service in JAX-RS Jersey. I have deployed in the Tomcat 7.0. Now I am exposing my web service URL to third party client. I want to put validation mechanism that includes getting host name i.e. the client host name that is using my service. I would like to match with our database entered host name. How to get the host name of the client?
Here is my web.xml:
<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/intellixservices/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>secureRESTFilter</filter-name>
<filter-class>com.astroved.intellix.security.SecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>secureRESTFilter</filter-name>
<url-pattern>/intellixservices/*</url-pattern>
</filter-mapping>
Now I am creating a SecurityFilter class implementing Filter. inside doFilter() method -
#Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpRes = (HttpServletResponse)res;
String url = "http://localhost:8888/IntellixWebApi/intellixservices/dnareport";
System.out.println("In security filter");
req.getRequestDispatcher(url).forward(req, res);
chain.doFilter(httpReq, httpRes);
}
But it is not forwarding to the next URL. In Resource class, it is returning xml/json type.
Have you considered using a filter ? not sure if this will be a good design, but you can get the values in the doFilter method using request.getRemoteHost()
request.getRemoteAddr() and do your validation
edit:
forgot about client behind proxy.. this Getting IP address of client link might help

Is it possible for a servlet filter to work out which servlet will handle the request

I'm writing a filter that performs logging and I need to disable this logging if the request is going to end up at a certain servlet.
Is there any way for the filter to know which servlet will handle the request?
You might want to setup servlet filter mapping to not fire it in case of requests for particular servlet altogether.
Example configuration could look like this assuming that there is one DefaultServlet that should not be impacted by filter and two other servlets FirstServlet and SecondServlet which have to be affected.
<filter-mapping>
<filter-name>MyFilter</filter-name>
<servlet-name>FirstServlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<servlet-name>SecondServlet</servlet-name>
</filter-mapping>
You can assign url pattern which are to be filtered
e.g.
<filter>
<filter-name>Admin</filter-name>
<filter-class>com.nil.FilterDemo.AdminFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Admin</filter-name>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
This filter will run for every single request handled by the servlet engine with /admin mapping.
I always think that you should be able to make exceptions to url-patterns in a web.xml e.g. if you could do something like this:
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>
<match>/resources/*</match>
<except>/resouces/images/blah.jpg</except>
</url-pattern>
but you can't so that's no help to you!
You obviously have access to the URL in the Filter through the request object so you could do something like this:
public void doFilter(ServletRequest sRequest, ServletResponse sResponse,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)sRequest;
if(!request.getRequestURI.equals("/resources/images/blah.jpg")) {
doLogging();
}
chain.doFilter();
}
(hard-coded here but you'd probably read it from a property file) although this may not be of use to you as you mentioned servlets in your query as opposed to URL patterns.
EDIT: another thought. If you don't mind doing your logging after the servlet has completed you could do something like this:
public void doFilter(ServletRequest sRequest, ServletResponse sResponse,
FilterChain chain) throws IOException, ServletException {
sRequest.setAttribute("DO_LOGGING", new Boolean(true));
chain.doFilter();
Boolean doLogging = (Boolean)sRequest.getAttribute("DO_LOGGING");
if(doLogging) {
doLogging();
}
}
and your servlet that you want to exclude from logging can just set that attribute to false.
public void doGet(HttpServletRequest req,
HttpServletResponse res) throws IOException {
req.setAttribute("DO_LOGGING", new Boolean(false));
// other stuff
}

Categories

Resources