web-dev-qa-db-fra.com

Comment déconnecter manuellement un utilisateur avec Spring Security?

La réponse est probablement simple: comment déconnecter manuellement l'utilisateur actuellement connecté dans la sécurité de printemps? Est-il suffisant d'appeler:

SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false); 

?

67
Erik

Dans le conteneur Servlet 3.0, la fonctionnalité de déconnexion de Spring est intégrée à servlet et il vous suffit d'appeler logout() sur votre HttpServletRequest. Encore besoin d'écrire un contenu de réponse valide.

Selon documentation (Printemps 3.2):

La méthode HttpServletRequest.logout () peut être utilisée pour déconnecter l'utilisateur actuel.

Cela signifie généralement que le SecurityContextHolder sera effacé, la session HttpSession sera invalidée, toute authentification "Mémoriser mes informations" sera nettoyée, etc.

35
Piotr Müller

Il m'est difficile de dire avec certitude si votre code est suffisant. Cependant, l'implémentation standard de Spring-security de la déconnexion est différente. Si vous jetiez un coup d'oeil à SecurityContextLogoutHandler, vous verriez qu'ils le font:

    SecurityContextHolder.clearContext();

De plus, ils invalident facultativement la HttpSession:

    if (invalidateHttpSession) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }
    }

Vous pouvez trouver plus d'informations dans une autre question sur la déconnexion dans Spring Security et en regardant le code source de org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler .

66
Grzegorz Oledzki

J'utilise le même code dans LogoutFilter, en réutilisant les LogoutHandlers comme suit:

public static void myLogoff(HttpServletRequest request, HttpServletResponse response) {
    CookieClearingLogoutHandler cookieClearingLogoutHandler = new CookieClearingLogoutHandler(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
    SecurityContextLogoutHandler securityContextLogoutHandler = new SecurityContextLogoutHandler();
    cookieClearingLogoutHandler.logout(request, response, null);
    securityContextLogoutHandler.logout(request, response, null);
}
20
gibaholms

Pour déconnecter un utilisateur dans une application Web, vous pouvez également le rediriger vers la page de déconnexion. Le LogoutFilter fait alors tout le travail pour vous.

L'URL de la page de déconnexion est défini dans la configuration de la sécurité:

<sec:http ...>
  ...
  <sec:logout logout-url="/logout" logout-success-url="/login?logout_successful=1" />
  ...
</sec:http>
10
James

Vous pouvez également utiliser SessionRegistry en tant que:

sessionRegistry.getSessionInformation(sessionId).expireNow();

Si vous souhaitez forcer la déconnexion de toutes les sessions d'un utilisateur, utilisez la méthode getAllSessions et appelez expireNow pour chaque information de session.

Modifier
Ceci nécessite ConcurrentSessionFilter (ou tout autre filtre de la chaîne), vérifie SessionInformation et appelle tous les gestionnaires de déconnexion, puis effectue une redirection.

10
Ritesh

new SecurityContextLogoutHandler().logout(request, null, null);

2
Tiago

Récemment, nous avons dû implémenter la fonctionnalité de déconnexion à l'aide de Spring-security 3.0.5. Bien que cette question ait déjà reçu une réponse ci-dessus, je publierai le code complet, ce qui aiderait certainement un utilisateur novice comme moi :)

Configuration dans Spring-security.xml

 <http auto-config="false" lowercase-comparisons="false" use-expressions="true">
     <custom-filter position="LOGOUT_FILTER" ref="logoutFilter" />
 </http>

<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <beans:constructor-arg name="logoutSuccessHandler" ref="xxxLogoutSuccessHandler" />
    <beans:constructor-arg name="handlers">
        <beans:list>
            <beans:ref bean="securityContextLogoutHandler"/>
            <beans:ref bean="xxxLogoutHandler"/>
        </beans:list>
    </beans:constructor-arg>
    <beans:property name="filterProcessesUrl" value="/logout"/>
</beans:bean>
<beans:bean id="XXXLogoutSuccessHandler" class="com.tms.dis.sso.XXXLogoutSuccessHandler"/>
<beans:bean id="securityContextLogoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
    <beans:property name="invalidateHttpSession" value="true"/>
</beans:bean>
<beans:bean id="XXXLogoutHandler" class="com.tms.dis.sso.XXXLogoutHandler"/>

Ici j'ai créé deux classes personnalisées

  1. XXXLogoutHandler qui implémentera org.springframework.security.web.authentication.logout.LogoutHandler et remplacera la méthode logout ().
  2. XXXLogoutSuccessHandler qui implémentera la méthode org.springframework.security.web.authentication.logout.LogoutSuccessHanlder et remplacera la méthode onLoguoutSuccess (). Dans la méthode XXXLogoutSuccessHandler.onLogoutSuccess (), appelez la méthode redirectStrategy.sendRedirect () qui déconnecte l'utilisateur vers l'URL cible particulière.
  3. org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler effectue la tâche qui consiste à invalider la session de l'utilisateur.

J'espère que cela vous aidera et donnera la bonne direction au starter

Note: N'a intentionnellement pas posté de code pour une implémentation personnalisée.

2
Nayan

Faites simplement comme ceci (ceux commentés par "vous concerne"):

    Authentication auth = SecurityContextHolder.getContext().getAuthentication(); // concern you

    User currUser = userService.getUserById(auth.getName()); // some of DAO or Service...

    SecurityContextLogoutHandler ctxLogOut = new SecurityContextLogoutHandler(); // concern you

    if( currUser == null ){
        ctxLogOut.logout(request, response, auth); // concern you
    }
2
loulou

D'accord, j'utilise les éléments suivants, par exemple, dans mon contrôleur pour me déconnecter et rediriger l'utilisateur vers la page de connexion au printemps sécurité 4.2.3

SecurityContextHolder.clearContext();

if(session != null)
    session.invalidate();

return "redirect:/login";
0
Hany Sakr