简体   繁体   中英

Logout is not working in Spring Security

I am writing a security application with Spring Security 4.0. As part of that I want to make a logout call. It is simply giving Request method 'POST' not supported. Here is my code:

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

If you use CSRF, you have to use HTTP POST (with a <form> in your JSP) instead of HTTP GET (with a <a> in your JSP), see Spring Security Reference :

18.5.3 Logging Out

Adding CSRF will update the LogoutFilter to only use HTTP POST. This ensures that log out requires a CSRF token and that a malicious user cannot forcibly log out your users.

One approach is to use a form for log out. If you really want a link, you can use JavaScript to have the link perform a POST (ie maybe on a hidden form). For browsers with JavaScript that is disabled, you can optionally have the link take the user to a log out confirmation page that will perform the POST.

For example, see Spring Security Reference :

37.5.1 Automatic Token Inclusion

Spring Security will automatically include the CSRF Token within forms that use the Spring MVC form tag. For example, the following 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> 

You can also try this in your JSP because I think your JSP is incorrect. Replace your given code with the following code:

<form action="/j_spring_security_logout">

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

</form>

In your case you are not submitting a form, you are simply making a get request to j_spring_security_logout but it requires a CSRF token with a POST request, so it will return the error message you're getting.

Edit: undo the changes you have made from the previous answer because this is just a modification to what you already have.

I solve this problem in my project. The code as follows:

    @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.
    }


I don't know whether you can accept this way. If you open CSRF,you must use post to request the logout url. In spring security4, the CSRF default open. This documents will give you more information. 18.5.3 Logging out 18.5.3 Logging Out

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM