【问题标题】:Why is my session still alive为什么我的会话还活着
【发布时间】:2016-05-06 08:39:23
【问题描述】:

我正在使用带有 redis 支持的会话的 spring。 如果我访问该站点,我会看到会话已添加到数据库中。 然后我在数据库上运行flushdb。 然后我尝试访问该站点,会话仍然存在(我有相同的会话 ID。)redis 键不同,但会话 ID 是相同的。 会话是否存储在 Redis 之外的其他地方?这是预期的吗?

使用windows 64位redis 2.8.2400。

一些 pom 依赖项。

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>1.6.2.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.2</version>
    </dependency>

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.8.0</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
        <version>1.0.2.RELEASE</version>
    </dependency>


    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>4.0.3.RELEASE</version>
    </dependency>
 <!--  -->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>4.0.3.RELEASE</version>
    </dependency>

相关豆类

<beans:bean id="RedisHttpSessionConfiguration" 
    class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" />
<beans:bean
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    p:port="6379" />

一些 web.xml

<listener>
        <listener-class>com.mysite.listeners.sessionStarted</listener-class>
    </listener>

<filter>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

关闭会话的控制器函数

RequestMapping(value = "/closeSession", method = RequestMethod.GET)
    public String closeSession(HttpSession session, HttpServletRequest request) {
        logger.info("Closeing Session (greri002 for testing).");
        session.invalidate();
        //request.logout();
        SecurityContextHolder.getContext().setAuthentication(null);
        return "OK";
    }

【问题讨论】:

  • 您使用的是 Spring Security 吗?你用的是什么服务器?
  • imo - java 配置要好得多,而且是 spring 的 xml 配置。

标签: spring spring-security redis


【解决方案1】:

Spring 安全性正在管理您的会话,将数据存储在 redis 中。如果您计划能够在节点之间共享会话数据,则只需要引入 redis 之类的东西。

存储安全信息的 Spring 的 SecurityContext。 https://docs.spring.io/spring-security/site/docs/current/apidocs/org/springframework/security/core/context/SecurityContext.html

假设您使用的服务器支持 3.0 Servlet,您只需在 HttpServletRequest 对象上调用 logout()。一个 Spring MVC 示例 -

@RequestMapping(value="/me/logout", method=RequestMethod.GET)
public @ResponseBody String logout(HttpServletRequest request) throws ServletException {
    request.logout();
    return "OK";
}

http://docs.spring.io/spring-security/site/docs/3.2.1.CI-SNAPSHOT/reference/htmlsingle/#servletapi-logout

如果您无权访问 HttpServletRequest,您可以这样做

SecurityContextHolder.getContext().setAuthentication(null);

还要确保您已正确注销 http 配置。他是我的

    <sec:logout logout-url="/logout"
                delete-cookies="JSESSIONID,jsessionid"
                invalidate-session="true"
                success-handler-ref="myLogoutFilter"/>

【讨论】:

  • 我有一个调用 session.invalidate(); 的 /closeSession 映射,为什么这也不起作用?
  • 我试过了,还是不行,在贴上代码。
  • 我将 request.logout() 与 spring4 和 tomcat8 一起使用。您的应用服务器需要支持 Servlet 3.0
  • setAuth(null) 确实有效,实际上,只是没有触发应该在创建新会话时触发的侦听器,这会导致在会话上设置一个变量来告诉我这是一个新的会话并强制逻辑发生。你知道为什么这个监听器没有被触发吗,当用户第一次访问网站时它会触发。
  • closeSession 确实将它从 redis 中删除,但实际上,我的会话 id 仍然没有消失,它仍然存在,这就是没有触发监听器的原因。
猜你喜欢
  • 2014-05-21
  • 2012-01-10
  • 2012-02-23
  • 1970-01-01
  • 2023-03-22
  • 2011-05-04
  • 2012-10-02
  • 1970-01-01
  • 2012-07-13
相关资源
最近更新 更多