web-dev-qa-db-fra.com

Sécurité de printemps: 404 en déconnexion

Lorsque j'essaie d'accéder à l'URL de déconnexion de mon application Spring, j'obtiens une erreur 404 et No mapping found for HTTP Request with URI [/logout] in DispatcherServlet with name 'mvc-dispatcher' dans le journal de mon serveur.

J'ai déjà essayé L'appel à j_spring_security_logout ne fonctionnant pas , Problème avec la déconnexion de la sécurité Spring et à peu près tous les résultats associés sur SO.

J'inclus les fichiers de configuration complets car la structure XML Spring n'est pas encore claire pour moi.

Ma configuration de sécurité:

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.xsd">

    <http pattern="/resources/**" security="none" />

    <http auto-config="true">
        <intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <intercept-url pattern="/**" access="ROLE_USER" />
        <form-login login-page="/login" default-target-url="/"/>
        <logout logout-url="/logout" />
        <csrf />
    </http>

    <global-method-security secured-annotations="enabled" />

    <authentication-manager>
        <authentication-provider user-service-ref="userDetailsService" />
    </authentication-manager>

</beans:beans>

Mon web.xml est ceci:

<web-app version="2.5" xmlns="http://Java.Sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://Java.Sun.com/xml/ns/javaee http://Java.Sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <display-name>XYZ</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/*-config.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

Comment faire fonctionner la page de déconnexion?

22
Thom Wiggers

Si vous utilisez la déconnexion avec CSRF, vous devez effectuer un POST. Voir http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf-logout

50
Rob Winch

J'ai eu le même problème après avoir migré de Spring 3.2 à 4, mais je voulais me déconnecter en utilisant un lien sur la vue.

Le doco Spring ( http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf-include-csrf-token-form ) explique comment le faire dans le vue.

J'ai utilisé cet extrait de code dans le JSP pour effectuer la déconnexion:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<form:form action="${pageContext.request.contextPath}/logout" method="POST">
    <input type="submit" value="Logout" />
</form:form>
7
Tom Saleeba

Afin de résoudre ce problème, il est généralement nécessaire de convertir un lien de déconnexion en un bouton de formulaire POST avec un jeton CSRF masqué, ce qui peut être réalisé de la manière suivante:

<a href="#" onclick="document.getElementById('logout-form').submit();"> Logout </a>

<form id="logout-form" action="<c:url value="/logout"/>" method="post">
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
0
gdrt