Spring Security注销无法与Spring 4 CORS一起使用

6

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

所有请求都正常工作,但是我无法注销我的用户,因为 /logoutOPTIONS 请求是由 Spring Security 处理的。

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

2个回答

9
在使用Spring Security时,建议使用 CorsFilter。您需要确保在 Spring Security 的 FilterChainProxy 之前对 CorsFilter 进行排序。
有关使用 CorsFilter 的详细信息,请参见 Spring Data Rest and Cors。此问题的区别可能在于只想为注销 URL 注册。例如:
@Bean
public CorsFilter corsFilter() {

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true); // you USUALLY want this
    // likely you should limit this to specific origins
    config.addAllowedOrigin("*"); 
    config.addAllowedHeader("*");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("PUT");
    source.registerCorsConfiguration("/logout", config);
    return new CorsFilter(source);
}

1
你知道如何在使用WebMvcConfigurer时执行此操作吗?请参考以下链接:https://spring.io/guides/gs/rest-service-cors/ ? 这种方法似乎不起作用:registry.addMapping("/logout").allowedOrigins("http://localhost:8100").allowCredentials(true); - user1689987

-1

我知道有点晚了。我在我的Angular2浏览器应用程序中遇到了同样的问题,即由于未返回CORS头Access-Control-Allow-Origin,/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)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接