2016-11-30 1 views
1

Ich schreibe eine Sicherheitsanwendung mit Spring Security 4.0. Dazu möchte ich einen Logout Call machen. Es gibt einfach Request-Methode 'POST' nicht unterstützt. Hier ist mein Code:Abmeldung funktioniert nicht in Spring Security

feder security.xml

<security:http auto-config="true"> 
    <security:access-denied-handler error-page="/denied"/> 
     <security:form-login login-page="/login" 
     username-parameter="j_username" 
     password-parameter="j_password" 
     login-processing-url="/j_spring_security_check" 
     authentication-failure-url="/login?failed=true" 
     default-target-url="/home" always-use-default-target="true"/> 
     <security:custom-filter ref="secfilter" before="FILTER_SECURITY_INTERCEPTOR" /> 

     <security:logout invalidate-session="true" logout-url="/j_spring_security_logout" logout-success-url="/login"/> 
     <!-- <security:logout logout-url="/j_spring_security_logout" logout-success-url="/login"/> --> 

    <security:csrf /> 
</security:http> 

jsp

<a href="j_spring_security_logout"> <button class="logoutbtn">logout</button></a> 
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 

Antwort

4

Wenn Sie CSRF verwenden, haben Sie POST HTTP verwenden (mit einem <form> in Ihrer JSP) anstelle von HTTP GET (mit einem <a> in Ihrer JSP), siehe Spring Security Reference:

18.5.3 Logging

Durch Hinzufügen von CSRF wird der LogoutFilter so aktualisiert, dass er nur HTTP POST verwendet. Dadurch wird sichergestellt, dass für die Abmeldung ein CSRF-Token erforderlich ist und dass ein böswilliger Benutzer die Benutzer nicht zwangsweise ausloggen kann.

Ein Ansatz besteht darin, ein Formular zum Abmelden zu verwenden. Wenn Sie wirklich einen Link möchten, können Sie JavaScript verwenden, damit der Link einen POST ausführt (d. H. Möglicherweise in einem versteckten Formular). Bei Browsern mit deaktiviertem JavaScript können Sie den Link optional dazu verwenden, den Benutzer zu einer Abmeldebestätigungsseite zu führen, die den POST ausführt.

Siehe zum Beispiel Spring Security Reference:

37.5.1 Automatische Token Inclusion

Spring Security automatisch die CSRF-Token in Formularen enthalten, die die Spring MVC-Formular-Tag verwenden. Zum Beispiel im Anschluss an die JSP:

<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" 
    xmlns:c="http://java.sun.com/jsp/jstl/core" 
    xmlns:form="http://www.springframework.org/tags/form" version="2.0"> 
    <jsp:directive.page language="java" contentType="text/html" /> 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> 
    <!-- ... --> 

    <c:url var="logoutUrl" value="/logout"/> 
    <form:form action="${logoutUrl}" 
      method="post"> 
    <input type="submit" 
       value="Log out" /> 
    <input type="hidden" 
       name="${_csrf.parameterName}" 
       value="${_csrf.token}"/> 
    </form:form> 

    <!-- ... --> 
</html> 
</jsp:root> 
0

ich dieses Problem in meinem Projekt zu lösen. Der Code wie folgt:

@RequestMapping(value="/j_spring_security_logout", method = RequestMethod.GET) 
    public String logoutPage (HttpServletRequest request, HttpServletResponse response) { 
     Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 
     if (auth != null){ 
      new SecurityContextLogoutHandler().logout(request, response, auth); 
      logger.info("logout ok"); 
     } 
     return "redirect";//You can redirect wherever you want, but generally it's a good practice to show login screen again. 
    } 


Ich weiß nicht, ob Sie auf diese Weise annehmen kann. Wenn Sie CSRF öffnen, müssen Sie die Abmelde-URL per Post anfordern. Im Frühjahr security4, der CSRF standardmäßig geöffnet. Diese Dokumente geben Ihnen mehr Informationen. 18.5.3 Logging out 18.5.3 Abmelden

+1

es mir funktioniert, aber ich habe diesen Code nicht verstehen.Können Sie mir bitte eine Erklärung geben? Wird die Sitzung ungültig? –

1

Sie können dies auch in Ihrer JSP versuchen, weil ich denke, dass Ihre JSP falsch ist. Ersetzen Sie Ihren gegebenen Code mit dem folgenden Code:

<form action="/j_spring_security_logout"> 

    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 
    <input type="submit" value="logout"> 

</form> 

In Ihrem Fall, dass Sie kein Formular einreichen, Sie machen einfach eine GET-Anforderung an j_spring_security_logout aber es erfordert eine CSRF-Token mit einer POST-Anfrage, so wird es zurückkehren die Fehlermeldung, die Sie erhalten.

Edit: rückgängig machen die Änderungen, die Sie von der vorherigen Antwort gemacht haben, weil dies nur eine Änderung ist, was Sie bereits haben.

Verwandte Themen