目前我们的遗留应用程序的Spring CSRF解决方案存在问题,因为CSRF实现更改了默认Spring安全性Spring安全配置的行为:
...
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 }
从代码质量的角度来看,这种方法通常并不好.所以,有两个问题:
在Spring中进行如此严格的实现的原因是什么,并且没有提供覆盖它的任何可见的可能性(特别是我提供了代码示例如何创建它)?
修复上述问题的任何好方法.
M. Deinum.. 8
您描述的行为是行为,如果您没有显式配置注销支持但只启用它,您明确配置它将使用该配置.
@Override protected void configure(HttpSecurity http) throws Exception { http .logout() .logoutRequestMatcher(new AntPathRequestMatcher("/logout")); }
这也被记录在参考指南中.
然而,真正的解决方案是你不应该使用控制器来实现额外的注销功能,而是使用LogoutHandler.这将很好地与Spring Security集成,您不需要重定向/转发到不同的URL.
您描述的行为是行为,如果您没有显式配置注销支持但只启用它,您明确配置它将使用该配置.
@Override protected void configure(HttpSecurity http) throws Exception { http .logout() .logoutRequestMatcher(new AntPathRequestMatcher("/logout")); }
这也被记录在参考指南中.
然而,真正的解决方案是你不应该使用控制器来实现额外的注销功能,而是使用LogoutHandler.这将很好地与Spring Security集成,您不需要重定向/转发到不同的URL.