web-dev-qa-db-fra.com

Comment activer la session et définir le délai d'expiration de la session dans Spring Security

Spring Security est nouveau pour moi et je travaille sur une fonctionnalité de connexion, déconnexion et expiration de session. J'ai configuré mon code en faisant référence à this document. Mon code est ci-dessous:

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

Remplacez la classe AbstractSecurityWebApplicationInitializer

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

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

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

}

J'ai besoin d'éclaircissements pour savoir si je le fais bien, si cela semble bon, puis où je dois configurer le délai d'expiration de la session. Je le fais entièrement basé sur l'annotation.

22
raju vaishnav

J'ai été capable de résoudre le problème ci-dessus en ajoutant la configuration ci-dessous dans web.xml uniquement. tout meilleur moyen sera accepté.

 <session-config>
    <session-timeout>20</session-timeout>
</session-config>
13
raju vaishnav

Si vous utilisez JavaConfig et que vous ne voulez pas utiliser XML, vous pouvez créer un HttpSessionListener et utiliser getSession().setMaxInactiveInterval(), puis dans la Initializer ajouter le auditeur dans 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");
    }
}

Puis dans l'initialiseur:

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

Lorsque vous utilisez application.properties, définissez la propriété server.session.timeout= valeur est en secondes.

8
JJ Roman

Différentes façons de configurer le délai d'expiration de la session (maxInactiveInterval) dans la sécurité de printemps.

1. En ajoutant la configuration de session dans web.xml (d'après la réponse de raju vaishnav)

2. En créant une implémentation de HttpSessionListener et en l'ajoutant au contexte de servlet (d'après la réponse de munilvc)

3. En enregistrant votre AuthenticationSuccessHandler personnalisé dans la configuration de sécurité printanière et en définissant un intervalle inactif maximal de session dans la méthode onAuthenticationSuccess.

Cette implémentation a des avantages

  1. En cas de réussite de la connexion, vous pouvez définir une valeur différente de maxInactiveInterval pour différents rôles/utilisateurs.

  2. En cas de succès de la connexion, vous pouvez définir un objet utilisateur dans une session. Vous pouvez donc accéder à cet utilisateur dans n’importe quel contrôleur de la session.

Inconvénient: vous ne pouvez pas définir de délai de session pour un utilisateur anonyme (utilisateur non authentifié)

Créer un gestionnaire 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());
    }
}

Enregistrer le gestionnaire de réussite

Dans Java moyen de configuration

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

De manière xml config

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

Le code de travail est disponible dans mon dépôt github Le code de travail est disponible sous deux formes

1. Méthode de configuration XML

2. Java

Si vous souhaitez avoir une fonction de déconnexion automatique et une minuterie qui s'affiche lorsque la session est sur le point d'expirer, si l'utilisateur remplit le formulaire mais n'est pas soumis, il peut prolonger la session en cliquant sur le bouton Conserver la session en cours. Si vous souhaitez implémenter la déconnexion automatique, reportez-vous à réponse au débordement de pile lors de la déconnexion automatique à l'expiration du délai de session . J'espère que cela pourrait aider.

0