CORS interfering with Spring Security oauth2

SrThompson :

I'm having problems trying to get a token from oauth/token from the browser. I have a Spring Boot application with Spring Security and Spring Security oauth, and I'm trying to authenticate from a javascript SPA in a different port.

When CORS is disabled in the backend, I can get tokens from the oauth endpoints no problem, using either Postman or the terminal, but I can't get them from javascript since the CORS preflight fails.

If I enable CORS, the preflight succeeds, but now I get an InsufficientAuthenticationException saying "There's no client authentication. Try adding an appropriate authentication filter". From what I can gather, that's because Spring Security fails to get the principal from the request.

Does anyone have a suggestion on how to deal with this?

SrThompson :

Apparently the Oauth2 endpoints and filters get processed before getting to the Spring Security filter chain, so adding CORS filters normally wouldn't work, but adding a CORS filter bean with high order priority ended up working.

This is my dedicated configuration class for CORS (adapted from the official spring guide, I'll be tweaking it later)

@Configuration
public class CorsConfig {
//IMPORTANT: it has to be a normal configuration class, 
//not extending WebMvcConfigurerAdapter or other Spring Security class
    @Bean
    public FilterRegistrationBean customCorsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:3000");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));

        //IMPORTANT #2: I didn't stress enough the importance of this line in my original answer, 
        //but it's here where we tell Spring to load this filter at the right point in the chain
        //(with an order of precedence higher than oauth2's filters)
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=463872&siteId=1