Spring Security exit does not work with Spring 4 CORS

I recently tried the new built-in CORS-Support in Spring 4 . This feature is great, and I want to implement it in my Spring Boot / AngularJS application.

The whole request works fine, but I cannot log out of my user because OPTIONS-Request to is /logouthandled by Spring Security .

Is it possible to handle OPTIONS-Request before Spring Security , or should I add CORS headers in LogoutSuccessHandler?

+4
source share
2 answers

When working with Spring Security, it is recommended that you use CorsFilter . You must make sure that you order CorsFilterbefore Spring Security FilterChainProxy.

More information on usage CorsFiltercan be found in Spring Data Rest and Cors . For this reason, the difference is most likely that you only want to register for the exit URL. For example:

@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);
}
+7
source

, . /logout, Angular2 - , CORS Access-Control-Allow-Origin /logout. , /logout , CORS , . , . , , :

  • LogoutHandler ()
  • LogoutSuccessHandler onLogoutSuccess()
  • Spring

, LogoutSuccessHandler, LogoutHandler. LogoutSuccessHandler ( ) - , . LogoutHandler . Spring -boot REST, Groovy ( 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 your uncle.
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(new TodosLogoutSuccessHandler())
                .addLogoutHandler(new TodosLogoutHandler())
                .invalidateHttpSession(true)
}
-1

Source: https://habr.com/ru/post/1619021/


All Articles