Java Servlet - 当servlet安全时,不同的JSESSION ID。为什么?

时间:2014-11-05 10:47:59

标签: java tomcat servlets web.xml jsessionid

我删除了我的先例帖子以重新创建更清晰的内容。有关信息,我已简化代码以使其更简单。

我告诉你我的问题。

我的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.
    }
}

servlet显示带有消息HellWorld的html页面,并包含DWR(Direct Web Remoting)javascript文件。从servlet / dwr /.

中检索DWR javascript文件

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>

servlet / HelloWorld和/ dwr已经发布。登录基于tomcat用户数据库:

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

Http请求/响应:

对于HelloWorld servlet调用

enter image description here

对于DWR servlet调用(engine.js)

enter image description here

对于DWR servlet调用(util.js)

enter image description here

对于DWR servlet调用(_System.pageLoaded.dwr)

enter image description here

正如您可以看到每个请求的 JSESSIONID更改,这是我的问题,我有一段时间无法解决...

我最近几天仍在进步。我现在知道问题仅在servlet安全时出现

    <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>

如果删除此安全性,则每个请求都返回相同的JSESSIONID。为什么? 我说这与DWR无关。当我调用servlet返回另一个JS,比如jQuery时,我遇到了同样的问题。

你能帮助我吗?

你可以在这个链接上找到部署到tomcat(Tomcat 7)的战争来发现问题:

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

您可以在此链接上找到代码来源:

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

非常感谢。

2 个答案:

答案 0 :(得分:1)

我没有检查过战争,但这可能是Tomcat 7中默认启用的会话固定问题。它会在进行身份验证时更改会话ID。检查更多并尝试关闭,看看它是您的问题http://java.dzone.com/tips/turning-session-fixation

答案 1 :(得分:0)

的确,如果我设置了changeSessionIdOnAuthentication =&#34; false&#34;在Context.xml中,可以使用

<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>

但是我看到http请求被做了2次:

enter image description here

是否有其他解决方案不会影响安全性? Servlet过滤器还是其他?

它实际上是阻塞的,因为它第一次从数据库中检索数据并在会话中设置它们。在第二个请求中,因为jsessionid更改,数据不再在会话中,必须再次检索...

感谢您的帮助