0

I'm using spring security in a tomcat server. How can I change the default session timeout ?

I've tried modifying the web.xml with:

<session-config>
         <session-timeout>1</session-timeout>
</session-config>

This does not seem to work.

I also read that spring boot uses the parameter server.servlet.session.timeout, but I don't use spring boot.

gus.jz
  • 13
  • 1
  • 2
  • 5
  • https://stackoverflow.com/a/54195305/6622913 – Istiaque Hossain Dec 04 '19 at 10:17
  • This is what I've tried, as said in my question. But it does not seem to work. More specifically, I still see in the logs `firing Filter: 'SecurityContextPersistenceFilter'`and then `Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT`, even though 1 minute as expired. – gus.jz Dec 04 '19 at 10:42
  • Timeout is 1 minute-ish. Tomcat has a reaper thread to kill timedout sessions, however that runs about every minute. So it can take more then a minute actually to clean the sessions. – M. Deinum Dec 04 '19 at 11:38
  • I waited far more than a minute (say, 10 minutes), and nothing happens... Are you sure that the configuration I wrote is supposed to force the user to reauthenticate after 1 minute? – gus.jz Dec 04 '19 at 12:41

2 Answers2

0

Different ways to configure session timeout time(maxInactiveInterval) in spring security.

  1. By addinng session config in web.xml

  2. By creating implementation of HttpSessionListener and adding it to servlet context.(from munilvc's answer)

  3. By registering your custom AuthenticationSuccessHandler in spring security configuration, and setting session maximum inactive interval in onAuthenticationSuccess method.

This implementation has advantages

  • On login success, You can set different value of maxInactiveInterval for different roles/users.

  • On login success, you can set user object in session, hence user object can be accessed in any controller from session.

Disadvantage: You can not set session timeout for ANONYMOUS user(Un-authenticated user)

  • Create AuthenticationSuccessHandler Handler

     public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
    
     public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
             throws IOException 
     {
         Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
         if (roles.contains("ROLE_ADMIN"))
         {
             request.getSession(false).setMaxInactiveInterval(60);
         }
         else
         {
             request.getSession(false).setMaxInactiveInterval(120);
         }
         //Your login success url goes here, currently login success url="/"
         response.sendRedirect(request.getContextPath());
     }
     }
    

Register success handler

In Java Config way

@Override
protected void configure(final HttpSecurity http) throws Exception
{
    http
        .authorizeRequests()
            .antMatchers("/resources/**", "/login").permitAll()
            .antMatchers("/app/admin/*").hasRole("ADMIN")
            .antMatchers("/app/user/*", "/").hasAnyRole("ADMIN", "USER")
        .and().exceptionHandling().accessDeniedPage("/403")
        .and().formLogin()
            .loginPage("/login").usernameParameter("userName")
            .passwordParameter("password")
            .successHandler(new MyAuthenticationSuccessHandler())
            .failureUrl("/login?error=true")
        .and().logout()
            .logoutSuccessHandler(new CustomLogoutSuccessHandler())
            .invalidateHttpSession(true)
        .and().csrf().disable();

    http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
}

In xml config way

<http auto-config="true" use-expressions="true" create-session="ifRequired">
    <csrf disabled="true"/>

    <intercept-url pattern="/resources/**" access="permitAll" />
    <intercept-url pattern="/login" access="permitAll" />

    <intercept-url pattern="/app/admin/*" access="hasRole('ROLE_ADMIN')" />
    <intercept-url pattern="/" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
    <intercept-url pattern="/app/user/*" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />

    <access-denied-handler error-page="/403" />

    <form-login 
        login-page="/login"
        authentication-success-handler-ref="authenticationSuccessHandler"
        authentication-failure-url="/login?error=true" 
        username-parameter="userName"
        password-parameter="password" />

    <logout invalidate-session="false" success-handler-ref="customLogoutSuccessHandler"/>

    <session-management invalid-session-url="/login?expired=true">
        <concurrency-control max-sessions="1" />
    </session-management>
 </http>

 <beans:bean id="authenticationSuccessHandler" class="com.pvn.mvctiles.configuration.MyAuthenticationSuccessHandler" />
ave4496
  • 2,950
  • 3
  • 21
  • 48
Blank
  • 90
  • 7
  • Thanks for the answer. I'm not sure I understand it though. I was hoping this could be done in a xml configuration file, without adding code. Is that not possible? – gus.jz Dec 04 '19 at 10:38
  • It can be done like you said, but did you change something in the "application.properties" file? you've got there a "server.servlet.session.timeout" value. P.S. this value is in Seconds. Also you did not mention what you wanted, if you want to deactivate the timeout you can set it to zero. – Blank Dec 04 '19 at 10:53
0

Keep in mind that this values is in seconds

<session-config>
         <session-timeout>1</session-timeout>
</session-config>

And this value will be rounded to the minutes.

If server does not receive any requests from e.g you GUI, It will wait at least 1 min and then expire session.