[英]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.