简体   繁体   English

注销在Spring Security中不起作用

[英]Logout is not working in Spring Security

I am writing a security application with Spring Security 4.0. 我正在用Spring Security 4.0编写一个安全应用程序。 As part of that I want to make a logout call. 作为其中的一部分,我想进行登出电话。 It is simply giving Request method 'POST' not supported. 它只是在提供不支持的请求方法“ POST”。 Here is my code: 这是我的代码:

spring-security.xml 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 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 : 如果使用CSRF,则必须使用HTTP POST (在JSP中带有<form> )而不是HTTP GET (在JSP中带有<a> ),请参阅Spring Security Reference

18.5.3 Logging Out 18.5.3注销

Adding CSRF will update the LogoutFilter to only use HTTP POST. 添加CSRF会将LogoutFilter更新为仅使用HTTP POST。 This ensures that log out requires a CSRF token and that a malicious user cannot forcibly log out your users. 这样可以确保注销需要CSRF令牌,并且恶意用户不能强制注销用户。

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). 如果您确实想要一个链接,则可以使用JavaScript使该链接执行POST(即,以隐藏形式)。 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. 对于禁用了JavaScript的浏览器,您可以选择使该链接将用户带到将执行POST的注销确认页面。

For example, see Spring Security Reference : 例如,请参阅Spring Security Reference

37.5.1 Automatic Token Inclusion 37.5.1自动令牌包含

Spring Security will automatically include the CSRF Token within forms that use the Spring MVC form tag. Spring Security将在使用Spring MVC表单标签的表单中自动包含CSRF令牌。 For example, the following JSP: 例如,以下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. 您也可以在JSP中尝试此操作,因为我认为您的JSP不正确。 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. 在您不提交表单的情况下,您只是向j_spring_security_logout发出了一个get请求,但是它需要带有POST请求的CSRF令牌,因此它将返回您得到的错误消息。

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. 如果打开CSRF,则必须使用post来请求注销URL。 In spring security4, the CSRF default open. 在spring security4中,CSRF默认打开。 This documents will give you more information. 本文档将为您提供更多信息。 18.5.3 Logging out 18.5.3 Logging Out 18.5.3注销 18.5.3注销

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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