簡體   English   中英

注銷在Spring Security中不起作用

[英]Logout is not working in Spring Security

我正在用Spring Security 4.0編寫一個安全應用程序。 作為其中的一部分,我想進行登出電話。 它只是在提供不支持的請求方法“ POST”。 這是我的代碼:

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

如果使用CSRF,則必須使用HTTP POST (在JSP中帶有<form> )而不是HTTP GET (在JSP中帶有<a> ),請參閱Spring Security Reference

18.5.3注銷

添加CSRF會將LogoutFilter更新為僅使用HTTP POST。 這樣可以確保注銷需要CSRF令牌,並且惡意用戶不能強制注銷用戶。

一種方法是使用表單注銷。 如果您確實想要一個鏈接,則可以使用JavaScript使該鏈接執行POST(即,以隱藏形式)。 對於禁用了JavaScript的瀏覽器,您可以選擇使該鏈接將用戶帶到將執行POST的注銷確認頁面。

例如,請參閱Spring Security Reference

37.5.1自動令牌包含

Spring Security將在使用Spring MVC表單標簽的表單中自動包含CSRF令牌。 例如,以下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> 

您也可以在JSP中嘗試此操作,因為我認為您的JSP不正確。 將您的給定代碼替換為以下代碼:

<form action="/j_spring_security_logout">

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

</form>

在您不提交表單的情況下,您只是向j_spring_security_logout發出了一個get請求,但是它需要帶有POST請求的CSRF令牌,因此它將返回您得到的錯誤消息。

編輯:撤消對上一個答案所做的更改,因為這只是對現有內容的修改。

我在我的項目中解決了這個問題。 代碼如下:

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


我不知道你是否可以接受這種方式。 如果打開CSRF,則必須使用post來請求注銷URL。 在spring security4中,CSRF默認打開。 本文檔將為您提供更多信息。 18.5.3注銷 18.5.3注銷

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM