当前位置: 首页 > 知识库问答 >
问题:

在Spring Boot时使用Spring会话(JDBC)扩展超时

沈鸿光
2023-03-14

我使用Spring Boot和Spring会话来控制一个使用ReactJS作为前端的应用程序。我的问题很简单,我尝试了几种方法来处理,但都没有成功。

React部分使用AJAX在登录后调用Spring REST服务(我也使用Spring Security),这至少需要30分钟。之后,会话停止,所有调用都会收到一个302,并以登录页面作为响应。这是意料之中的。

但我的问题是:有什么更好的方法来延长后端的生存时间(超过默认的30分钟)?

    // Gradle portion
    compile('org.springframework.boot:spring-boot-devtools')
    compile('org.springframework.boot:spring-boot-starter-jdbc')
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-aop')
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.security:spring-security-test:4.1.1.RELEASE')

    // Cache configuration - JDBC
    compile('org.springframework.session:spring-session:1.2.2.RELEASE')
    compile('org.springframework.session:spring-session-jdbc:1.2.2.RELEASE')
    compile('org.springframework.boot:spring-boot-starter-jdbc')

我习惯补充:

// A 24 hours long session
server.session.timeout = 86400 

这样,我就可以在SPRING_SESSION表中看到我的会话存储在MAX_INACTIVE_INTERVAL=86400中。一切似乎都很好...只有30分钟。在第31分钟,我尝试点击另一个激发AJAX调用的页面,我会收到302到我的登录页面作为响应。

我使用另一种方法获得了完全相同的行为,通过Java在Auth成功上设置:

@Component
public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    @Value("${server.session.timeout}")
    private String defaultSessionTimeoutInSeconds;

    @Override
    public void onAuthenticationSuccess(
            HttpServletRequest request,
            HttpServletResponse response,
            Authentication authentication) throws ServletException, IOException {

        request.getSession().setMaxInactiveInterval(Integer.parseInt(defaultSessionTimeoutInSeconds));
        super.onAuthenticationSuccess(request, response, authentication);
    }
}

当然,我可以在数据库存储的会话中验证我的号码,但30分钟后会话再次被删除。

那么将Spring会话超时延长到30分钟以上的正确方法是什么呢?既然MAX_INACTIVE_INTERVAL没有做我认为应该做的事情,那么正确的方法是什么?

我可以使用任何库的最新版本。

PS:当我的AJAX调用(基于JQuery)接收到/login重定向时,我可以考虑另一个重定向整个浏览器的解决方案,以及回退的情况。

提前谢了。

更新:

我尝试了以下方法:

@Scheduled(cron = "0 * * * * *")
public void cleanUpExpiredSessions() {
    long now = System.currentTimeMillis();
    long maxInactiveIntervalSeconds = (this.defaultMaxInactiveInterval != null)
            ? this.defaultMaxInactiveInterval
            : MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;

    final long sessionsValidFromTime = now - (maxInactiveIntervalSeconds * 1000);

更新2

更仔细地查看html" target="_blank">代码,在我的示例中,当实例化JdbcOperationsSessionRepository时,它是由JDBCHTTPSessionConfiguration#SessionRepository创建的

具体而言:

@Bean
public JdbcOperationsSessionRepository sessionRepository(
        @Qualifier("springSessionJdbcOperations") JdbcOperations jdbcOperations,
        PlatformTransactionManager transactionManager) {
    JdbcOperationsSessionRepository sessionRepository =
            new JdbcOperationsSessionRepository(jdbcOperations, transactionManager);
    String tableName = getTableName();
    if (StringUtils.hasText(tableName)) {
        sessionRepository.setTableName(tableName);
    }
    sessionRepository
            .setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds); // Always 1800 (private Integer maxInactiveIntervalInSeconds = 1800;)
    if (this.lobHandler != null) {
        sessionRepository.setLobHandler(this.lobHandler);
    }
    if (this.springSessionConversionService != null) {
        sessionRepository.setConversionService(this.springSessionConversionService);
    }
    else if (this.conversionService != null) {
        sessionRepository.setConversionService(this.conversionService);
    }
    else if (deserializingConverterSupportsCustomClassLoader()) {
        GenericConversionService conversionService = createConversionServiceWithBeanClassLoader();
        sessionRepository.setConversionService(conversionService);
    }
    return sessionRepository;
}
    import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;

@EnableJdbcHttpSession(tableName="MYSCHEMA.SPRING_SESSION", maxInactiveIntervalInSeconds = 86400)
public class HttpSessionConfig {
}

但是,如果我在新会话中保留相关的SPRING_SECURITY_CONTEXT(SPRING_SESSION_ATTRIBUTES表)信息,整个会话和属性将在30分钟后删除。

在一个疯狂的测试中,我做了一个登录,删除了我的会话的SPRING_SECURITY_CONTEXT属性,会话仍然存在...

默认的会话清理器是正确的,它不是这里的违规者…

    2016-10-04 12:18:02,081 8808479 [pool-1-thread-1] INFO  d.s.t.s.ScheduledCacheRefresher - Checking refreshable caches now. 
2016-10-04 12:19:00,001 8866399 [pool-1-thread-1] DEBUG o.s.s.j.JdbcOperationsSessionRepository - Cleaning up sessions older than Mon Oct 03 12:19:00 BRT 2016 
2016-10-04 12:19:02,050 8868448 [pool-1-thread-1] DEBUG o.s.s.j.JdbcOperationsSessionRepository - Cleaned up 0 expired sessions 
2016-10-04 12:19:02,051 8868449 [pool-1-thread-1] INFO  d.s.t.s.ScheduledCacheRefresher - Checking refreshable caches now. 
2016-10-04 12:20:00,001 8926399 [pool-1-thread-1] INFO  d.s.t.s.ScheduledCacheRefresher - Checking refreshable caches now. 
2016-10-04 12:20:00,003 8926401 [pool-1-thread-1] DEBUG o.s.s.j.JdbcOperationsSessionRepository - Cleaning up sessions older than Mon Oct 03 12:20:00 BRT 2016 
2016-10-04 12:20:02,063 8928461 [pool-1-thread-1] DEBUG o.s.s.j.JdbcOperationsSessionRepository - Cleaned up 0 expired sessions

因此,检查SPRING_SECURITY_CONTEXT的任何其他内容仍然有大约30分钟的默认超时,它会触发整个会话无效。

我正试图添加更多断点来解决它。:)

共有1个答案

鄂曦之
2023-03-14

必须在application.properties文件中设置server.session.timeout。请参阅本文档:服务器属性

 类似资料:
  • 问题内容: 我有一个spring / jdbc / oracle 10g应用程序。Oracle服务器数据库时区设置为GMT + 2 JVM时区设置为GMT + 2(即使对于我而言这无关紧要)。 我有一个执行某些日期操作的存储过程。问题是,即使我未在代码/配置中明确设置会话时区,会话时区也不同于数据库时区(GMT)。 据我所知,会话时区默认情况下等于数据库时区。知道为什么会话时区与数据库时区不同,或

  • 我的应用程序使用SpringWebMVC框架运行,没有Spring Boot。现在,我想使用spring会话JDBC将会话存储到应用程序使用的数据库中。我在网上找到的所有示例都使用spring boot,如果没有使用spring boot,那么他们使用的数据源配置是嵌入式数据库,如下所示: 我有使用HikariCP的数据源配置,我希望spring会话使用此数据源配置。 如何使用当前配置与sprin

  • 我需要在代码中实现JDBC会话。为此,我按照https://www.baeldung.com/spring-session-jdbc. 我导入了maven依赖项并添加了spring。一场应用程序中的存储类型=jdbc。属性文件。然后我运行程序,它抛出了一系列错误。我不能确切地理解它在尖叫什么。如果有人能帮助我,我真的很感激。 这是我得到的错误:

  • 为了将会话保存在数据库中,我在这里使用这个示例实现了Spring会话JDBC。我在使用@Autow的会话范围时遇到问题:我JavaClass如下: 然后我在会话\u范围内注册这个bean,如下所示: 在控制器中,我正在对其进行布线并尝试使用: 当我尝试运行时,出现以下错误:

  • 在 HTTP 协议中,当客户端不再处于活动状态时没有显示的终止信号。这意味着当客户端不再处于活跃状态时可以使用的唯一机制是超时时间。 Servlet 容器定义了默认的会话超时时间,且可以通过 HttpSession 接口的 getMaxInactiveInterval 方法获取。开发人员可以使用HttpSession 接口的 setMaxInactiveInterval 方法改变超时时间。这些方法

  • 问题内容: 我正在使用spring / spring-security 3.1,希望在用户注销(或会话超时)时采取一些措施。我设法完成了注销操作,但对于会话超时,我无法使其正常工作。 在web.xml中,仅指定了ContextLoaderListener(这可能是问题吗?),当然还有DelegatingFilterProxy。 我使用这样的自动配置。 当用户单击注销时,将调用注销处理程序,这将对数