New session always being created when using getSession() - java

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.

Related

Access same name cookie in different application tabs

I have an application running on localhost:8080 and it create a cookie with name jsessionid. Now I need to open another tabs for different application which is running on localhost:8090 which also create a cookie with same name that is jsessionid.
I need to access cookie of first application tab in second application tab..
how can I access both cookies... many tried but no luck...
You can write a servlet filter that would run before page gets rendered (in the atlassian-plugin.xml)
<servlet-filter name="My Filter" i18n-name-key="home-page-redirect-filter.name"
key="home-page-redirect-filter" class="mypackage.CookieFilter"
location="before-dispatch" weight="100">
<description key="home-page-redirect-filter.description">Some description</description>
<url-pattern>WHEN_TO_RUN</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</servlet-filter>
and then you can intercept cookies
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
Cookie[] myCookies=request.getCookies();
//do something with cookies
}
Looks like I misread your question. JSESSIONID is an httponly cookie and you won't be able to use document.cookie in the javascript to get it.
Maybe take a look at Jsoup Cookies for HTTPS scraping and Sending POST request with username and password and save session cookie for some ideas.

AppEngine domain redirect using web.xml

I want to intercept all incoming requests e.g.
http://subdomain.domain.org/path/to/resource
to
https://appengineid.appspot.com/path/to/resource
for any possible /path/to/resource
Is this possible with the app engine web.xml deployment descriptor?
When I search this topic all the documentation or questions/answers relate to transforming/translating the /path/to/resource part of a request rather than the subdomain.domain.tld part?
Thanks
QUESTION EDIT/UPDATE:
Both of the above URLs point to the exact same instance of an app engine application. I don't want to URL pattern match on the /path/to/resource because this would "match" requests to both URLs. I want to URL pattern match on the domain part of the URL, so that any requests to subdomain.domain.org are redirected to appengineid.appspot.com, and then, so that no cycle is encountered any requests to appengineid.appspot.com are ignored by the redirecting filter and are handled by the rest of the web deployment descriptor.
It seems to be that a Filter will solve your problem.
You create a new filter in your web.xml, like this:
<filter>
<filter-name>yourFilterName</filter-name>
<filter-class>com.acme.filter.YourNewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>yourFilterName</filter-name>
<url-pattern>/path/to/resource/*</url-pattern>
</filter-mapping>
Your filter class will be something like this:
public class YourNewFilter extends MyGenericFilter implements Filter {
public void doFilter(final ServletRequest request,
final ServletResponse response,
FilterChain chain)
throws java.io.IOException, javax.servlet.ServletException {
ServletContext context= getServletContext();
req.getRequestURL().toString() // use this method to get the end of the URL
RequestDispatcher rd= context.getRequestDispatcher("https://appengineid.appspot.com/path/to/resource/" + end of the URL
);
rd.forward(request, response);
}
}
It is gonna intercept all requests in one domain and dispatch it to another.

getSession() always creates a new session

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.

Setting cookie from doFilter method

I have a filter class with doFilter method. In the doFilter method, I am setting a cookie as follows
HttpServletResponse httpResp=(HttpServletResponse)servletResponse;
Cookie myCookie=new Cookie("test","");
myCookie.setValue("testValue");
myCookie.setPath("/");
myCookie.setDomain(".mydomain.com");
httpResp.addCookie(myCookie);
filterChain.doFilter(servletRequest,servletResponse);
Should this ideally work? Setting a cookie in httpResp(HttpServletResponse) object and then just forwarding servletResponse(ServletResponse) object
Strangely the cookie is set for some clients but for some others the cookie is not set. I have checked the cookie settings on client's browser and it looks ok.
You can use the HttpServletResponseWrapper to enable the filter to control the response over down stream filters or servlets are
https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletResponseWrapper.html
Here is a pretty good explanation of the wrapper: https://stackoverflow.com/a/7047298/1676293
This will work except you need to refactor the code to:
filterChain.doFilter(servletRequest,servletResponse);
HttpServletResponse httpResp=(HttpServletResponse)servletResponse;
Cookie myCookie=new Cookie("test","");
myCookie.setValue("testValue");
myCookie.setPath("/");
myCookie.setDomain(".mydomain.com");
httpResp.addCookie(myCookie);
Add the cookie after the filterChain call so that another filter/servlet cannot do something that conflicts.

Servlet's sendRedirect() kills my session attributes

I am working on a webapp in WinXP, Eclipse Indigo and Google web plugin.
I have a simple form that takes a value from user (e.g email) , passes it to a servlet named SignIn.java that processes it and saves the email value to the session.
The SignIn code is very simple , here is what its doGet mostly does:
String email = req.getParameter("email"); //getting the parameter from html form
...
...
HttpSession session = req.getSession(); //create a new session
session.setAttribute("email", email);
So far so good, I've verified that the values aren't null at this point. Now comes the problem, I want to redirect to another servlet (ShowOnline.java) that needs to do some more processing. When I write
resp.sendRedirect(resp.encodeRedirectURL("/ShowOnlineServlet"));
ShowOnline gets null session values (the same email attribute I saved a second before is now null)
When I write
getServletConfig().getServletContext().getRequestDispatcher("/ShowOnlineServlet");
everything is OK, the email attribute from before isn't null!
What is going on? sendRedirect() just makes your browser send a new request, it shouldn't affect the session scope. I have checked the cookies and they are fine (it is the same session from before for sure since it is the first and only session my webapp creates and furthermore I even bothered and checked the sesison ID's and they're the same on both requests).
Why would there be a difference between sendRedirect() and forward()? The easy solution would be to use forward() but I want to get to the bottom of this before I just let go , I think it is important for me to understand what happened. I'm not sure I like the idea of not knowing what's going on on such basic concepts (my whole webapp is very simple and basic at this point since I'm a beginner).
Any thoughts ideas or suggestions would be warmly welcome !
If your SignIn servlet is only saving a request parameter (email), then you could also replace the servlet with a filter, e.g. SignInFilter.
SignInFilter would contain the same logic as your SignIn servlet (copying the email from the request parameters to the session), but would call the next item in the chain (which will be your ShowOnline servlet) instead of doing any redirect/forward.
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession();
String email = req.getParameter("email");
session.setAttribute("email", email);
chain.doFilter(req, res); // continue to 'ShowOnline'
}
Set up your form to POST to the ShowOnline servlet instead, and configure your new SignInFilter to execute before ShowOnline (servlet mapping omitted below for brevity).
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<filter>
<filter-name>SignInFilter</filter-name>
<filter-class>com.example.SignInFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SignInFilter</filter-name>
<url-pattern>/ShowOnline</url-pattern>
</filter-mapping>
</web-app>
As far as my knowledge, sendRedirect() just redirects the control to another page without transfering the associated request & response object of parent page, but RequestDispatcher(object) will dispatch the ServletRequest and ServletResponse to the page mentioned in path argument { getServletContext().getRequestDispatcher("path")} after that you can either forward the objects to that page or include the objects. So by this container becomes assured that he has to use the previous request and response object from of the parent page instead of creating new one.
Specially if you are using session management the best option is RequestDispatcher.
Hope that answers the question.
To All :- Please correct me if i am wrong.
#rs

Categories

Resources