Spring Security Logout不适用于Spring 4 CORS

时间:2015-12-08 11:28:14

标签: java angularjs spring spring-mvc spring-security

最近我在 Spring 4 中尝试了新的内置 CORS-Support 。这个功能很棒,我想在我的 Spring Boot / AngularJS 应用程序中实现它。

  

所有请求都正常但我无法注销我的用户,因为OPTIONS - 对/logout的请求由 Spring Security 处理。

是否可以在 Spring Security 之前处理OPTIONS - 请求,还是应该在LogoutSuccessHandler中附加 CORS-Headers

2 个答案:

答案 0 :(得分:7)

使用Spring Security时,建议使用CorsFilter。您需要确保在Spring Security&{39}之前订购CorsFilter

有关使用FilterChainProxy的详细信息,请参阅Spring Data Rest and Cors。对于此问题,您可能希望仅注册注销URL。例如:

CorsFilter

答案 1 :(得分:-1)

我知道这有点晚了。由于在/ logout响应中没有返回CORS头Access-Control-Allow-Origin,因此我的Angular2浏览器应用程序拒绝/ logout遇到了同样的问题。 / logout似乎在到达CORS过滤器之前处理,因此没有得到标题。我尝试了上面的解决方案,但它对我不起作用。所以,我尝试了下一个解决方案,效果很好:

  • 创建LogoutHandler实现类并实现logout()
  • 创建一个LogoutSuccessHandler实现类并实现onLogoutSuccess()
  • 将两个类连接到Spring安全配置

原来我不需要LogoutSuccessHandler类,只需要LogoutHandler。 LogoutSuccessHandler(未显示)只是一个空实现,其中包含日志记录语句。 LogoutHandler如下。这是一个用Groovy编写的Spring-boot REST应用程序的片段(非常类似于java)

@Slf4j
class TodosLogoutHandler implements LogoutHandler {

/**
 * For some reason the spring-session logout gets processed before the request
 * reaches the CORS filter so the response doesn't get the allow-origin header
 * which then causes the browser to reject the logout response. I tried a bunch
 * of other methods of trying to include /logout to the CORS filter but they
 * didn't work so figured a logout handler would be a place I could manually
 * set the header to persuade the browser to accept the response - it worked!!
 * @param request
 * @param response
 * @param authentication
 */
  @Override
  void logout(
        HttpServletRequest request,
        HttpServletResponse response,
        Authentication authentication) {

    response.setHeader("Access-Control-Allow-Origin", "*")

    log.info("TodosLogoutHandler logging you out of the back-end app.")
  }
}

然后在安全配置类中将它连接在一起,扩展WebSecurityConfigurerAdapter,如下所示。显示注销部分的最后一部分是标准configure()方法的相关部分。

    @Override
  public void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()                 // Allow any CORS OPTIONS calls
            .antMatchers(HttpMethod.GET, "/priority", "/status").permitAll()    // Allow all ref data
            .anyRequest().authenticated()
            .and()
                .csrf().disable()
                .httpBasic().realmName("Spring REST Todos")
            .and()
                // Custom logout handler only exists to handle a CORS problem with /logout
                // where spring-session processes the logout request/response before it gets
                // to the CORS filter so it doesn't get the allow-origin header which  then
                // causes the browser to reject the /logout response. Manually set the
                // allow-origin header in the logout handler and Bob's your uncle.
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(new TodosLogoutSuccessHandler())
                .addLogoutHandler(new TodosLogoutHandler())
                .invalidateHttpSession(true)
}