Franck S
Franck S

Reputation: 113

Java Servlet - Different JSESSION ID when servlet are securise. Why?

I deleted my precedent post to recreate a clearer. For information, I have simplified the code to make it simpler.

I present you my problem.

My servlet HelloWorld :

public class HelloWorld extends HttpServlet {

    private String message;

    public void init() throws ServletException {
        // Do required initialization
        message = "Hello World";
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Set response content type
        response.setContentType("text/html");

        // session test
        System.out.println( request.getSession().getId() );

        PrintWriter out = response.getWriter();
        out.println("<html><head><script src='./dwr/engine.js'></script><script src='./dwr/util.js'></script></head><body><h1>Hello World</h1></body></html>");
    }

    public void destroy() {
        // do nothing.
    }
}

The servlet display a html page with message HellWorld and include DWR (Direct Web Remoting) javascript files. The DWR javascript files are retrieved from servlet /dwr/.

Web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <display-name>TestDWR2</display-name>

    <servlet>
        <servlet-name>HelloWorld</servlet-name>
        <servlet-class>test.HelloWorld</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloWorld</servlet-name>
        <url-pattern>/HelloWorld/*</url-pattern>
    </servlet-mapping>

    <servlet>
      <servlet-name>dwr-invoker</servlet-name>
      <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
        <init-param>
            <param-name>config</param-name>
            <param-value>WEB-INF/dwr.xml</param-value>
        </init-param>
        <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
      <servlet-name>dwr-invoker</servlet-name>
      <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Extranet resource</web-resource-name>
            <description>Extranet resources</description>
            <url-pattern>/HelloWorld/*</url-pattern>
            <url-pattern>/dwr/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>intranet_admin</role-name>
        </auth-constraint>
    </security-constraint>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>Extranet</realm-name>
    </login-config>

    <security-role>
        <description>Intranet Admin</description>
        <role-name>intranet_admin</role-name>
    </security-role>

</web-app>

The servlet /HelloWorld and /dwr are securised. The login is based on tomcat user database :

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
     <user username="tomcat" password="tomcat" roles="intranet_admin"/>
</tomcat-users>

Http request / response :

For HelloWorld servlet call

enter image description here

For DWR servlet call (engine.js)

enter image description here

For DWR servlet call (util.js)

enter image description here

For DWR servlet call (_System.pageLoaded.dwr)

enter image description here

As you can see the JSESSIONID change for each request and this is my problem I can not solve for some time...

I still progress last few days. I know now that the problem only appears when the servlets are secure :

    <web-resource-collection>
        <web-resource-name>Extranet resource</web-resource-name>
        <description>Extranet resources</description>
        <url-pattern>/HelloWorld/*</url-pattern>
        <url-pattern>/dwr/*</url-pattern>
    </web-resource-collection>

If a remove this security, each request return same JSESSIONID. Why? I said that this is not related to DWR. When I call a servlet to return another JS, such as jQuery, I encounter the same problem.

Can you help me?

You can find on this link, the war to deploy to tomcat (Tomcat 7) to discover the problem :

https://www.wetransfer.com/downloads/dd1729b56d26e94b9d9a5dcb264dce0c20141105104229/a623a93ec2bcbb8b3ac8e2695cbe646c20141105104229/b4bc1e

You can find on this link, the code source :

https://www.wetransfer.com/downloads/fd8a74c850a5beb32d6529576f15f42c20141105104405/6f89adba0c853d48e392edb1d3ca562620141105104405/f67f43

Thank you very much.

Upvotes: 1

Views: 879

Answers (2)

Franck S
Franck S

Reputation: 113

Indeed, If I set changeSessionIdOnAuthentication="false" in Context.xml, it works :

<Context path="/test" reloadable="true" docBase="D:\projects\test2\TestDWR" workDir="D:\projects\test2\TestDWR\work" >
<Valve className="org.apache.catalina.authenticator.BasicAuthenticator"
  changeSessionIdOnAuthentication="false" />
</Context>

But I see that http request are made 2 times :

enter image description here

Is there another solution that would not compromise safety? Servlet filter or other?

It's really blocking because on the first time a retrieve data from database and set them in session. And in second request, because jsessionid change, the data are no longer in session and must be again retrieved...

Thank you for your help

Upvotes: 0

Master Slave
Master Slave

Reputation: 28529

I didn't check the wars, but this could be a session fixation issue that is turned on by default in Tomcat 7. It basically changes the session ID when it becomes authenticated. Check more and try switching off just to see if its your issue http://java.dzone.com/tips/turning-session-fixation

Upvotes: 1

Related Questions