raju vaishnav
raju vaishnav

Reputation: 811

How to enable session and set session timeout in Spring Security

I am new to Spring Security and I am working on a login, logout, and session timeout feature. I have configured my code by referring to this document. My code looks below:

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests().antMatchers("/admin/**")
        .access("hasRole('ROLE_USER')").and().formLogin()
        .loginPage("/login").failureUrl("/login?error")
            .usernameParameter("username")
            .passwordParameter("password")
            .and().logout().logoutSuccessUrl("/login?logout").and().csrf();
    http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired");
}

Override the class AbstractSecurityWebApplicationInitializer

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    public boolean enableHttpSessionEventPublisher() {
        return true;
    }

}

I need clarification on whether I am doing it right, if it looks good, then where I need to setup the session timeout. I am doing it fully based on annotation.

Upvotes: 41

Views: 114951

Answers (8)

JJ Roman
JJ Roman

Reputation: 4570

When using application.properties set property server.session.timeout= value is in seconds.

EDIT

server.session.timeout is now deprecated and has been superseded by server.servlet.session.timeout=60s

NOTE

Tomcat will not allow you to set the timeout less than 60 seconds. See https://github.com/spring-projects/spring-boot/issues/7383.

Upvotes: 17

PraveenKumar Lalasangi
PraveenKumar Lalasangi

Reputation: 3543

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

1. By addinng session config in web.xml(from raju vaishnav's answer)

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

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

  2. 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" />
 

Working code is available in my github repository Working code is available in two forms

1. XML config way of implementation

2. JAVA config way of implementation

If you want to have automatic logout feature and timer which displays when session is about to expire, if user is filling form but not submitted then user can extend session by clicking on keep session alive button. If you want to implement auto logout refer stack overflow answer on auto logout on session timeout. Hope this will help.

Upvotes: 12

hema arun
hema arun

Reputation: 1

this will work:

@EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 84600)

Upvotes: 0

Abd Abughazaleh
Abd Abughazaleh

Reputation: 5565

Add the below in application.proprites

server.servlet.session.timeout= 

Upvotes: 0

New Bee
New Bee

Reputation: 430

In your application properties use server.servlet.session.timeout=1m (If a duration suffix is not specified, seconds will be used.)

By default it is 30 minutes.

Upvotes: 7

Komal Singh Sisodiya
Komal Singh Sisodiya

Reputation: 31

I handled it inside subclass of UsernamePasswordAuthenticationFilter You can get username by -

obtainUsername(request);

and apply user checks and set time out accordingly, like-

if(username.equalsIgnoreCase("[email protected]")) 
        {
        logger.debug("setting timeout 15 min");
        request.getSession(false).setMaxInactiveInterval(15*60);
        }

Upvotes: 0

munilvc
munilvc

Reputation: 522

If you are using JavaConfig and do not want to use XML you can create a HttpSessionListener and use getSession().setMaxInactiveInterval(), then in the Initializer add the listener in onStartup():

public class SessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent event) {
        System.out.println("session created");
        event.getSession().setMaxInactiveInterval(15);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
       System.out.println("session destroyed");
    }
}

Then in the Initializer:

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    super.onStartup(servletContext);
    servletContext.addListener(new SessionListener());
}

Upvotes: 35

raju vaishnav
raju vaishnav

Reputation: 811

I was able to solve above issue by adding below config in web.xml only. any better way will be accepted.

 <session-config>
    <session-timeout>20</session-timeout>
</session-config>

Upvotes: 19

Related Questions