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);
?
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.
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
.
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);
}
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>
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.
new SecurityContextLogoutHandler().logout(request, null, null);
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
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.
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
}
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";