Crystian182
Crystian182

Reputation: 79

CORS problems with Spring Security and Websocket

I am developing an Ionic app based on a Spring backend. I implemented Spring Security with JWT authentication. My app will have a chat room where users can talk each other in private or public chat. So, I am implementing a WebSocket system in order to get all updates in real time.

This is my Security Configuration:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Autowired
    private UserDetailsService userDetailsService;

    private AuthenticationManager authenticationManager;

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                .userDetailsService(this.userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
        return new JwtAuthenticationTokenFilter();
    }

   // configurazione Cors per poter consumare le api restful con richieste ajax
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("*");
        configuration.setAllowedMethods(Arrays.asList("POST, PUT, GET, OPTIONS, DELETE"));
        configuration.addAllowedHeader("*");
        configuration.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }


    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
         httpSecurity
         .csrf().disable()
         .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
         .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
         .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().cors().and()
         .authorizeRequests()
         .antMatchers(
                 HttpMethod.GET,
                 "/",
                 "/*.html",
                 "/favicon.ico",
                 "/**/*.html",
                 "/**/*.css",
                 "/**/*.js",
                 "/image/**").permitAll()
         .antMatchers("/socket/**").permitAll()
         .antMatchers("/public/**").permitAll().and()
         .authorizeRequests().anyRequest().authenticated().and();

         httpSecurity.headers().cacheControl();
    }

    @Bean
    public AuthenticationManager customAuthenticationManager() throws Exception {
        return authenticationManager();
    }
}

This is my WebSocket configuration:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer{
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/socket")
                .setAllowedOrigins("*")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/chat")
                .enableSimpleBroker("/subscribe");
    }
}

In this condition, I am currently facing this error:

Access to XMLHttpRequest at 'http://localhost:8080/SpringApp/socket/info?t=1547732425329' from origin 'http://localhost:8100' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Each call is working (i am perfectly authorized with jwt) but the WebSocket can't work.

So, I tried to simply remove the .cors() in configure method in my security configuration class. This lead me to an opposite problem:

error in chrome

Indeed, now WebSocket works perfectly, instead each api call gives me 401.

What's the correct way to resolve this problem? Thank you

Upvotes: 0

Views: 3079

Answers (1)

O. Schnieders
O. Schnieders

Reputation: 681

Yeah, I got the same error when I was working in a related issue in one of my projects. The solution was that I had to set the allowed-origin header value to the URL of my application. The wildcard value (*) is not allowed if you send credentials.

Upvotes: 0

Related Questions