Как включить сеанс и установить время ожидания сеанса в Spring Security

Привет, я новичок в Spring Security. Я работаю над функцией входа в систему, выхода из системы и времени ожидания сеанса. Я настроил свой код, ссылаясь на этот документ, мой код выглядит ниже.

@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");
    }

Переопределить класс AbstractSecurityWebApplicationInitializer

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

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

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

}

Тем не менее мне нужно уточнить, правильно ли я делаю, если это выглядит хорошо, то где мне нужно установить время ожидания сеанса. Я делаю это полностью на основе аннотации.

8 ответов

Решение

Мне удалось решить вышеупомянутую проблему, добавив ниже конфигурацию только в web.xml. любой лучший способ будет принят.

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

Если вы используете JavaConfig и не хотите использовать XML, вы можете создать HttpSessionListener и использовать getSession().setMaxInactiveInterval()затем в Initializer добавить слушателя в 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");
    }
}

Затем в инициализаторе:

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

При использовании application.properties задайте свойство server.session.timeout= значение в секундах.

Различные способы настройки времени ожидания сеанса (maxInactiveInterval) в Spring Security.

1. Путем добавления конфигурации сеанса в web.xml(из ответа Раджу Вайшнава)

2. Создав реализацию HttpSessionListener и добавив ее в контекст сервлета.(Из ответа munilvc)

3. Зарегистрировав свой собственный AuthenticationSuccessHandler в конфигурации безопасности Spring и установив максимальный интервал неактивности сеанса в методе onAuthenticationSuccess.

Эта реализация имеет преимущества

  1. При успешном входе в систему вы можете установить разные значения maxInactiveInterval для разных ролей / пользователей.

  2. При успешном входе в систему вы можете установить объект пользователя в сеансе, поэтому к объекту пользователя можно будет получить доступ в любом контроллере из сеанса.

Недостаток: нельзя установить таймаут сеанса для АНОНИМНОГО пользователя (неаутентифицированного пользователя)

Создать обработчик AuthenticationSuccessHandler

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());
    }
}

Зарегистрировать обработчик успеха

В режиме конфигурации Java

@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");
}

В режиме конфигурации xml

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

Рабочий код доступен в моем репозитории на github Рабочий код доступен в двух формах

1. Способ реализации конфигурации XML

2. Способ реализации конфигурации JAVA

Если вы хотите иметь функцию автоматического выхода из системы и таймер, который отображается, когда сеанс подходит к концу, если пользователь заполняет форму, но не отправляется, пользователь может продлить сеанс, нажав кнопку "Сохранить сеанс в активном состоянии". Если вы хотите реализовать автоматический выход из системы, обратитесь к ответу на переполнение стека при автоматическом выходе из системы по истечении времени ожидания сеанса. Надеюсь, это поможет.

В свойствах вашего приложения используйте server.servlet.session.timeout=1m(Если суффикс длительности не указан, будут использоваться секунды.)

По умолчанию это 30 минут.

Добавьте ниже в application.proprites

      server.servlet.session.timeout= 

это будет работать:

      @EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 84600)

Я обработал это внутри подкласса UsernamePasswordAuthenticationFilter. Вы можете получить имя пользователя:

obtainUsername(request);

и применить пользовательские проверки и установить время ожидания соответственно, например:

if(username.equalsIgnoreCase("komal-singh-sisodiya@xyz.com")) 
        {
        logger.debug("setting timeout 15 min");
        request.getSession(false).setMaxInactiveInterval(15*60);
        }
Другие вопросы по тегам