Spring-boot: server.session.timeout is not expiring session

Created on 14 Nov 2016  路  12Comments  路  Source: spring-projects/spring-boot

Hi,

According to the documentation on [this link(
http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html)
the session timeout property says:

server.session.timeout= # Session timeout in seconds.

So, I want to make the session to timeout after 5 seconds by using:

server.session.timeout=5

but the session is not expiring, also waited for 5min but didn't expire either.

I am using SprintBoot version 1.4.1.RELEASE with an embedded Tomcat. Not sure if it is worth it to mention that I'm using spring security as well to check users.

Regards

invalid

Most helpful comment

It's also worth noting that by default, and unlike Jetty and Undertow, Tomcat isn't very proactive about expiring sessions.

A background check for expired sessions is only performed once every 6th run of the container's background processor. By default, runs are performed every 30 seconds so it may take as long as 3 minutes after the session's expiry time has elapsed for it to actually expire.

For a session to expire more proactively a request with a session cookie that identifies an expired session must be made. Tomcat will then check if the session has expired before providing access to it.

All 12 comments

Unlike Jetty and Undertow, Tomcat only supports minute precision for session timeout. Any value that is greater than zero is converted to minutes with a minimum of 1 minute:

if (sessionTimeout > 0) {
    sessionTimeout = Math.max(TimeUnit.SECONDS.toMinutes(sessionTimeout), 1L);
}

In other words, a value of 5 should result in a one minute timeout on Tomcat. Can you please double-check that the session doesn't time out if you wait for at least one minute? If it doesn't time out, please provide a small sample project that reproduces the problem and the exact steps that you're taking to check the behaviour.

@wilkinsona I have tested with 120 and same problem, session is not expiring. Unfortunately I'm not able to provide a sample project for the moment. If you think it's possible I can upload my pom.xml, application.properties and SecurityConfig.java if needed

@fedepia You don't need to provide your production code, any small sample that replicates the issue will do. If it's not possible to replicate the issue from a small standalone application then perhaps something in your app is causing the session to remain alive?

It's also worth noting that by default, and unlike Jetty and Undertow, Tomcat isn't very proactive about expiring sessions.

A background check for expired sessions is only performed once every 6th run of the container's background processor. By default, runs are performed every 30 seconds so it may take as long as 3 minutes after the session's expiry time has elapsed for it to actually expire.

For a session to expire more proactively a request with a session cookie that identifies an expired session must be made. Tomcat will then check if the session has expired before providing access to it.

Thanks @wilkinsona, good to know. I'll try Jetty to see if I have the same problem.

@philwebb, I don't have any configuration my app it is just a bunch of webservices. The only configuration I use is this for spring security and anything else:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserRepository userRepository;

    private Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

    /**
     * Configures the http security
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Allows connections for test endpoints. Note MockWebServer needs this endpoint free for testing
        http.authorizeRequests().antMatchers("/test/**").permitAll();

        // Configure all requests to use header basic auth. 
        // CSRF is disabled meaning that session is not saved and all request will need auth.
        http
            .authorizeRequests()
                .anyRequest().fullyAuthenticated()
                .and().httpBasic()
                .and().csrf().disable();    
    }

    /**
     * Configure authentication to use User database table and Bcrypt to check passwords
     */
    @Override
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService());
        authProvider.setPasswordEncoder(new BCryptPasswordEncoder());

        auth.authenticationProvider(authProvider);
    }

    /**
     * Define the user details spring security with a custom implementation.
     * This custom implementation will use User repository and will search for users that are only active 
     */
    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsService() {

            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                User user = userRepository.findByUsernameAndActive(username, true);
                if (user != null) {
                    // Creates spring security User using CreditSesame user
                    return new org.springframework.security.core.userdetails.User(user.getUsername(),
                            user.getPassword(), true, true, true, true, AuthorityUtils.createAuthorityList("USER"));
                }

                logger.error("Could not find any active user '{}'", username );
                throw new UsernameNotFoundException("Could not find any active user '" + username + "'");
            }
        };
    }

}

I started to think that this might be related to Tomcat. Will post asap the result with Jetty

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Hey guys, we were a little busy but here is the sample project that we created where the problem was replicated. It a simple project where I tried to set the property "server.session.timeout" as seconds, minutes, but the session never expired. Hopefully you can help us, maybe we are missing something during the configuracion of Spring Boot.

Btw the endpoint that you can test is: http://localhost:8400/sample/product/

BD: MySQL
User bd: root
Password bd: root

Thanks in advance.

SampleTimeout.zip

@jesusalayo90 I can't reproduce the problem with the sample. Are you testing it with a browser? If so, you need to be aware that your browser will cache and re-send the basic authentication credentials so you get a new session every time. You can mimic this behaviour and see what's happening by using curl:

$ curl -u user:user -i localhost:8400/sample/product/
HTTP/1.1 200
Set-Cookie: JSESSIONID=7D8519591A620637E99C2C23BAD67187;path=/sample;HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: text/plain;charset=UTF-8
Content-Length: 19
Date: Thu, 24 Nov 2016 17:10:54 GMT

Service is running.
$ curl -u user:user -i localhost:8400/sample/product/
HTTP/1.1 200
Set-Cookie: JSESSIONID=D9C21B69CF55ADF22E9822E9DF65BA9E;path=/sample;HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: text/plain;charset=UTF-8
Content-Length: 19
Date: Thu, 24 Nov 2016 17:11:01 GMT

Service is running.

Note the different session id in the Set-Cookie header.

You can then make a request using the Cookie rather than basic auth credentials:

$ curl --cookie JSESSIONID=D9C21B69CF55ADF22E9822E9DF65BA9E -i localhost:8400/sample/product/
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: text/plain;charset=UTF-8
Content-Length: 19
Date: Thu, 24 Nov 2016 17:11:20 GMT

Service is running.

If you wait for over a minute and them make a request using the Cookie rather than credentials, you'll see that the session has timed out and the request is rejected:

curl --cookie JSESSIONID=D9C21B69CF55ADF22E9822E9DF65BA9E -i localhost:8400/sample/product/
HTTP/1.1 401
Set-Cookie: JSESSIONID=FBE70BDD1F74AD3AC3C6F6F74E6763A4;path=/sample;HttpOnly
WWW-Authenticate: Basic realm="Realm"
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 24 Nov 2016 17:12:57 GMT

{"timestamp":1480007662646,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/sample/product/"}

I have the same problem, although setting server.session.timeout=3600 in application.properties

the same problem I am facing but when I used with session management type as JDBC it is working. The only issue is with map session.

@Raghavender This issue is about the timeout of sessions managed by the embedded container and it sounds like you are using Spring Session which is responsible for its own timeout.

@Raghavender Please stop asking the same thing repeatedly. You have already had an explanation in the issue that you opened. If you have further questions about Spring Session, please ask on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

Was this page helpful?
0 / 5 - 0 ratings