【问题标题】:How can I get a list of all sessions in Spring?如何获取 Spring 中所有会话的列表?
【发布时间】:2018-09-07 09:48:15
【问题描述】:

我正在使用 Spring Boot 2 和 Gradle 开发一个 Web 应用程序。我目前实现了一个自定义记住我的机制(WITHOUT Spring Security),并且我还添加了一个系列 cookie,如 here 所述。

现在我想在令牌不匹配的情况下使所有用户的会话无效。我会得到用户的所有会话(我保存在“userSession”属性中的一个 Bean)。我该怎么办?

PS:我使用 Spring Security。

【问题讨论】:

  • @NikolayShevchenko:不,我不使用 Spring Security,所以没有 SessionRegistry。
  • 您的应用中没有 Spring 安全上下文?如果存在安全上下文 - 您拥有 Spring 开发人员 SessionRegistry 和 Spring 安全过滤器,通过从 cookie 中查找 JSESSIONID 来确定哪个用户发送请求。如果您没有 SecurityContext - 您可以使用一些参数进行 cookie 编码和解码。并且当参数更改时,您无法解码 cookie 文件并且它无效。但这不是一个好方法。

标签: java spring session spring-boot


【解决方案1】:

Spring 中有一个名为 Spring Session 的模块,可以轻松管理所有实际会话。 Link for Spring Session documentation

要运行它,你必须在 pom.xml 中添加依赖:

    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-jdbc</artifactId>
    </dependency>

并将一些配置属性添加到 application.properties:

spring.session.store-type=jdbc
spring.session.jdbc.initializer.enabled=true
spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-qlserver.sql 
spring.session.jdbc.table-name=SPRING_SESSION

在“spring.session.jdbc.schema=”中,您可以选择自己的数据库类型或使用像 H2 这样的嵌入式数据库。 Spring 将自动从存储会话的内置脚本中为会话创建表。

【讨论】:

    【解决方案2】:

    您必须创建一个自定义 HttpSession 持有者对象,该对象将持有您可以根据您的条件迭代和失效的活动会话。

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    
    @Configuration
    public class HttpSessionConfig {
    
        private static final Map<String, HttpSession> sessions = new HashMap<>();
    
        public List<HttpSession> getActiveSessions() {
            return new ArrayList<>(sessions.values());
        }
    
        @Bean
        public HttpSessionListener httpSessionListener() {
            return new HttpSessionListener() {
                @Override
                public void sessionCreated(HttpSessionEvent hse) {
                    sessions.put(hse.getSession().getId(), hse.getSession());
                }
    
                @Override
                public void sessionDestroyed(HttpSessionEvent hse) {
                    sessions.remove(hse.getSession().getId());
                }
            };
        }
    } 
    

    【讨论】:

    • 这意味着在应用程序的生命周期内所有会话都存在的对象。这对内存来说不是很贵吗?
    • 是和否取决于我们在会话中存储了多少数据,最佳做法是存储最少的信息。另一种选择是使用 SpringSession 将数据持久保存在 DB 等外部系统中,然后您可以获得活动会话,也适用于集群服务器。
    猜你喜欢
    • 1970-01-01
    • 2012-02-09
    • 2013-04-05
    • 2018-01-17
    • 2019-01-30
    • 2014-09-19
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    相关资源
    最近更新 更多