在Spring中处理新的HttpServletRequest时会引用旧的Session和cookie

时间:2015-02-09 00:29:15

标签: spring session cookies session-cookies session-management

使用Spring 3开发的My Restful服务应用程序部署在Tomcat7上。我使用名为Postman的Chrome应用程序来请求REST服务。

我在所有服务(非安全服务登录除外)之前放置了自定义过滤器,用于检查会话和应用程序特定的cookie。 如果cookie在传入的HttpServletRequest中不存在或无效,则此过滤器返回HTTP状态:403。过滤器(myCustomSecurityFilter)是Singleton作用域。

<security:intercept-url pattern="/services/v1/login" access="permitAll()" /> <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myCustomSecurityFilter" />

我观察到在特殊情况下使用旧的HttpServletRequest。请参阅以下方案

案例#1:所有请求均通过HTTPS。

  1. 删除所有Cookie并重新启动浏览器。

  2. 调用HTTPS serveice:.. \ services \ v1 \ account。由于必须在.. \ services \ v1 \ login之后调用此服务,因此需要403响应。实际回复:403。 将创建一个新会话,并由Tomcat返回JSESSIONID。比如,JSESSIONID_1。

  3. 请求.. \ services \ v1 \ login。预期和实际休息200-OK。 将创建一个新会话,并由Tomcat返回JSESSIONID。说,JSESSIONID_2。 此外,特定于应用程序的cookie将返回给客户端/浏说,App_cookie_1。
  4. 调用除.. \ services \ v1 \ account之外的任何其他服务。一切都很成功(200)。 Cookie JSESSIONID_2,App_cookie_1是按请求发送的,收到响应后也可以观察到相同的情况。 注意:此步骤并不重要。可以在有或没有该步骤的情况下再现步骤5。
  5. 请求.. \ services \ v1 \ account。预期:200。实际:403。 当我调试上面提到的SecurityFilter中的doFilter方法收到的HttpServletRequest时,我看到HttpServletRequest包含先前对同一服务的请求的旧cookie .. \ services \ v1 \ account。 即JSESSIONID_1。没有应用cookie。 我在httpServletRequest.getCookies()的帮助下检查了cookie 浏览器显示Cookies JSESSIONID_2,App_cookie_1。我确信Tomcat接收了Cookie JSESSIONID_2,App_cookie_1因为我启用了访问日志记录。 因此,Spring(我的代码或Spring框架之上的配置)将旧的HttpServletRequest传递给过滤器。但是怎么样?为什么呢?
  6. 请求.. \ services \ v1 \ account。预期:200。实际:200。 Cookie JSESSIONID_2,App_cookie_1是按请求发送的,收到响应后也可以观察到相同的情况。 因此,旧cookie只使用一次,在这种情况下也仅用于相同的服务(.. \ services \ v1 \ account)。
  7. Webapp在以下情况下按预期工作(上述步骤用数字表示): 案例2:1,2,3,4,5,6。除#2(登录请求)外,所有都是HTTPS请求。如果#2是HTTP请求,#5返回200!这也是一个惊喜。 案例3:2,3,4,5,6。 案例4:2,3,5,6。

    第4步并不重要。可以在有或没有该步骤的情况下再现步骤5。我把它放在这个位置来解释加载相同服务的先前请求并且对其他服务没有影响。 问题绝对不是.. \ services \ v1 \ account。因为我刚刚使用过这项服务。可以使用应用程序中的任何安全服务重复案例1。

    我尝试使用newSessio,migrateSession选项管理我的会话。

    <security:session-management session-fixation-protection="newSession">        
        <security:concurrency-control max-sessions="1" />
    </security:session-management>
    

    感谢您阅读我的问题。如果你能给出一些指示,那将是很棒的。 如果我不清楚,请告诉我。

1 个答案:

答案 0 :(得分:0)

(最近我遇到类似的问题时回答。即使问题太旧了)

..\services\v1\login

创建一个新会话,Tomcat返回一个JSESSIONID。

如何在此处创建会话?

假设它通常创建如下

HttpServletRequest.getSession(true);

服务器很有可能在这里获得旧会话。 你能试试吗

session.Invalidate()

 request.logout()

这样,任何打开的会话都会失效。之后您再次尝试创建会话

  HttpServletRequest.getSession(true);
相关问题