[英]Spring Security 4.x set logout method to GET with xml config
[英]Spring CSRF override “POST” logout behaviour in security XML config
目前我們的遺留應用程序的Spring CSRF解決方案存在問題,因為CSRF實現更改了默認Spring安全性Spring安全配置的行為:
<http pattern="">
...
<logout
logout-url="/logout"
delete-cookies="..."
success-handler-ref="logoutSuccessHandler"
/>
<csrf/>
</http>
org.springframework.security.config.annotation.web.configurers.LogoutConfigurer
注銷配置器。 根據Spring文檔:
添加CSRF會將LogoutFilter更新為僅使用HTTP POST。 這可確保注銷需要CSRF令牌,並且惡意用戶無法強制注銷您的用戶。
進行此更改的代碼如下:
private RequestMatcher getLogoutRequestMatcher(H http) {
if(logoutRequestMatcher != null) {
return logoutRequestMatcher;
}
if(http.getConfigurer(CsrfConfigurer.class) != null) {
this.logoutRequestMatcher = new AntPathRequestMatcher(this.logoutUrl, "POST");
} else {
this.logoutRequestMatcher = new AntPathRequestMatcher(this.logoutUrl);
}
return this.logoutRequestMatcher;
}
通常,對於CSRF保護,這種行為非常有意義。 但對於我來說,這種實現不靈活(為什么硬編碼實際的實現而不是autowire依賴?)是非常奇怪的。
問題是我們的應用程序是這樣構建的,即在常規Spring注銷之前,它會在Spring Controllers中執行額外的清理。 主要是它實現了Switch User功能,但是以自定義方式實現。 因此,更改注銷鏈接以執行POST不是一種選擇,因為主要是在自定義控制器上執行清理。
似乎為了使用指定的方法,只有一種可能的解決方案:
@RequestMapping(value = "/logout", method = RequestMethod.GET) //or it can be a post
public String logout() {
// 1. Perform Clean up
// 2. Decide whether to logout or redirect to other page
// 3. Perform redirect based on decision
}
//如果決定退出,則會轉到此Controller方法:
@RequestMapping(value = "csrflogout", method = RequestMethod.GET)
public void csrfLogout(){
//1 Create manual post request
//2. Copy session information
//3. Perform Post to logout URL that is specified in security xml
}
從代碼質量的角度來看,這種方法通常並不好。 所以,有兩個問題:
您描述的行為是行為,如果您沒有顯式配置注銷支持但只啟用它,您明確配置它將使用該配置。
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
}
這也被記錄在參考指南中。
然而,真正的解決方案是你不應該使用控制器來實現額外的注銷功能,而是使用LogoutHandler 。 這將很好地與Spring Security集成,您不需要重定向/轉發到不同的URL。
基本上,主要的復雜性是在Spring Security XML上下文中重寫logoutFilter,以使用org.springframework.security.web.util.matcher.AntPathRequestMatcher的默認實現(使用“GET”而不是“POST”請求)。 為了做到這一點,將幾個bean添加到安全xml上下文中:
<bean id="logoutAntPathRequestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="logout" />
</bean>
和注銷過濾器本身:
<bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg name="logoutSuccessHandler" ref="logoutSuccessHandler"/>
<constructor-arg name="handlers">
<list>
<ref bean="securityContextLogoutHandler" />
<ref bean="cookieClearingLogoutHandler" />
<ref bean="csrfLogoutHandler" />
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout"/>
<property name="logoutRequestMatcher" ref="logoutAntPathRequestMatcher"/>
</bean>
Internet Explorer 11更新后,我看到了同樣的錯誤。 CsrfConfigurer.class不為null,並且在注銷時需要發布。
if(http.getConfigurer(CsrfConfigurer.class) != null) {
this.logoutRequestMatcher = new AntPathRequestMatcher(this.logoutUrl, "POST");
} else {
this.logoutRequestMatcher = new AntPathRequestMatcher(this.logoutUrl);
}
我通過繞過logoutfilter並插入新的過濾器來解決我的問題
示例如下。
<beans:bean id="logoutAntPathRequestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<beans:constructor-arg value="/logout"/>
</beans:bean>
<beans:bean id="securityContextLogoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
</beans:bean>
<beans:bean id="cookieClearingLogoutHandler" class="org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler">
<beans:constructor-arg value="JSESSIONID"/>
</beans:bean>
<beans:bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg name="logoutSuccessUrl" value="/login"/>
<beans:constructor-arg name="handlers">
<beans:list>
<beans:ref bean="securityContextLogoutHandler" />
<beans:ref bean="cookieClearingLogoutHandler" />
</beans:list>
</beans:constructor-arg>
<beans:property name="filterProcessesUrl" value="/logout"/>
<beans:property name="logoutRequestMatcher" ref="logoutAntPathRequestMatcher"/>
</beans:bean>
<http>
...
<sec:custom-filter ref="logoutFilter" after="LOGOUT_FILTER"/>
...
</http>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.