15

server.session-timeout seems to be working only for embedded tomcat.

I put a log statement to check the session max interval time. After deploying the war file manually to tomcat, I realized that default session timeout value (30 min) was being used still.

How can I set session timeout value with spring-boot (not for embedded tomcat, but for a stand-alone application server)?

Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
led
  • 611
  • 4
  • 11
  • 18
  • In a spring boot I found that "Even though the session timeout can be easily configured by setting the server.sessiontimeout property in application.properties to our desired value in seconds". Is this true? if you just add session timeout in properties file it would work? – JayC Apr 28 '17 at 15:57
  • yes, spring boot session management would be using org.apache.catalina.session.StandardManage when you package spring boot project into a war, and deploy it in an outer container. aka, it would use that contain's web.xml session expire time. – Tiina Aug 23 '17 at 07:57
  • I recently read about [this topic](https://stackoverflow.com/questions/32501541/what-is-the-default-session-timeout-and-how-to-configure-it-when-using-the-sprin) and in version 1.5.7 it is called `server.session.timeout`. – rocksteady Oct 24 '17 at 08:45
  • 2
    For Springboot 2.1.x, it is now: server.servlet.session.timeout. More at https://docs.spring.io/spring-boot/docs/2.1.x/reference/html/common-application-properties.html. – tuan.dinh Apr 10 '19 at 02:04

8 Answers8

23

[Just in case someone finds this useful]

If you're using Spring Security you can extend the SimpleUrlAuthenticationSuccessHandler class and set the session timeout in the authentication success handler:

public class NoRedirectSavedRequestAwareAuthenticationSuccessHandler
       extends SimpleUrlAuthenticationSuccessHandler {

    public final Integer SESSION_TIMEOUT_IN_SECONDS = 60 * 30;

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

        request.getSession().setMaxInactiveInterval(SESSION_TIMEOUT_IN_SECONDS);

        // ...
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .loginProcessingUrl("/login")
            .successHandler(new NoRedirectSavedRequestAwareAuthenticationSuccessHandler())
            .failureHandler(new SimpleUrlAuthenticationFailureHandler())
            .and().httpBasic();
    }

}
informatik01
  • 16,038
  • 10
  • 74
  • 104
justin
  • 3,357
  • 1
  • 23
  • 28
  • I implement AuthenticationSuccessHandler interface. What's the difference in purpose between SimpleUrlAuthenticationSuccessHandler and AuthenticationSuccessHandler and what's better? – LosmiNCL Jul 14 '21 at 02:33
6

When you deploy a Spring Boot app to a standalone server, configuring the session timeout is done in the same way as it would be in any other war deployment.

In the case of Tomcat you can set the session timeout by configuring the maxInactiveInterval attribute on the manager element in server.xml or using the session-timeout element in web.xml. Note that the first option will affect every app that's deployed to the Tomcat instance.

Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • 1
    What if the application doesn't use web.xml but uses org.springframework.boot.web.servlet.FilterRegistrationBean in @SpringBootApplication/SpringBootServletInitializer ? – martin-g Mar 21 '17 at 13:35
  • Then you can configure it in server.xml as I said above – Andy Wilkinson Mar 21 '17 at 16:20
  • Or via Servlet APIs directly (https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSession.html#setMaxInactiveInterval(int)) in https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSessionListener.html#sessionCreated(javax.servlet.http.HttpSessionEvent). Just wanted to check whether Spring Web/Boot have support for this. Thanks! – martin-g Mar 21 '17 at 19:57
2

You've discovered, as I have, that there is no direct call in the Servlet API nor the Spring APIs for setting the session timeout. The need for it is discussed here and there, but it hasn't been addressed yet.

There's kind of a round-a-bout way to do what you want. You can configure a session listener that sets the timeout on the session. I came across an article with code examples at: http://fruzenshtein.com/spring-java-configuration-session-timeout

I hope that helps.

RichW
  • 2,004
  • 2
  • 15
  • 24
2

Based on justin's answer showing how to set session timeout using an AuthenticationSuccessHandler with Spring Security, I created a SessionTimeoutAuthSuccessHandler:

public class SessionTimeoutAuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
  public final Duration sessionTimeout;

  public SessionTimeoutAuthSuccessHandler(Duration sessionTimeout) {
    this.sessionTimeout = sessionTimeout;
  }

  @Override
  public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse res, Authentication auth) throws ServletException, IOException {
    req.getSession().setMaxInactiveInterval(Math.toIntExact(sessionTimeout.getSeconds()));
    super.onAuthenticationSuccess(req, res, auth);
  }
}

In use:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
      .anyRequest().authenticated()
      .and().formLogin().loginPage("/login")
      .successHandler(new SessionTimeoutAuthSuccessHandler(Duration.ofHours(8))).permitAll()
      .and().logout().logoutUrl("/logout").permitAll();   
  }
...
}

Edit Extending from SavedRequestAwareAuthenticationSuccessHandler rather than SimpleUrlAuthenticationSuccessHandler to ensure that original requests is not lost after re-authentication.

Brice Roncace
  • 10,110
  • 9
  • 60
  • 69
1

In your application.properties

#session timeout (in secs for spring, in minutes for tomcat server/container)
server.session.timeout=1

I tested it and is working! It turns out that tomcat take the property in minutes

Eduardo
  • 2,070
  • 21
  • 26
1

Use HttpSessionListener

@Configuration
public class MyHttpSessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent event) {
        event.getSession().setMaxInactiveInterval(30);
    }
}
Shapur
  • 498
  • 7
  • 17
0

Complementing the @Ali answer, you can also create a session.timeout variable in your application.yml file and use it in your class. This should work great with Spring Boot war and external Tomcat:

application.yml

  session:
    timeout: 480 # minutes

SessionListener (with @Configuration annotation)

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
class SessionListener implements HttpSessionListener {

    @Value("${session.timeout}")
    private Integer sessionTimeout;

    @Override
    public void sessionCreated(HttpSessionEvent event) {
        event.getSession().setMaxInactiveInterval(sessionTimeout);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {}

}
0

I used ServletContextInitializer

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@Configuration
public class MyServletContextInitializer implements ServletContextInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.setSessionTimeout(1);
    }
}
Amir
  • 1,638
  • 19
  • 26