Search code examples
javascripthtmlspring-bootspring-securitywebsocket

Spring Boot - Security - Websocket - Cannot load webjars / resource blocked due to MIME type (“”) mismatch errors


I'm using Spring Boot, Spring Security, Thymeleaf, Websockets.

I have the following dependencies in pom.xml:

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>sockjs-client</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>stomp-websocket</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.1.1-1</version>
        </dependency>

In an html file, I have the following references:

  <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
  <script src="/webjars/jquery/jquery.min.js"></script>
  <script src="/webjars/sockjs-client/sockjs.min.js"></script>
  <script src="/webjars/stomp-websocket/stomp.min.js"></script>

I have also tried placing the jars in the same directory as the html file like this:

<link href="bootstrap.min.css" rel="stylesheet" type="text/css">
<script src="jquery.min.js" type="text/javascript"></script>
<script src="sockjs.min.js" type="text/javascript"></script>
<script src="stomp.min.js" type="text/javascript"></script>
<script src="script.js" type="text/javascript"></script>

My SecurityFilterChain:

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http.csrf().disable().authorizeHttpRequests()


                .requestMatchers("/register").permitAll()
                .requestMatchers("/websocket").permitAll()
                .requestMatchers("/home").permitAll().and()
                .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login")
                .defaultSuccessUrl("/websocket", true).permitAll()
                .and()
                .logout()
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login?logout").permitAll();

        return http.build();
    }

When the html page tries to load, I keep getting the following errors (which are found in the browser's console):

The resource from “http://localhost:8080/bootstrap.min.css” was blocked due to MIME type (“”) mismatch (X-Content-Type-Options: nosniff).
websocket
The resource from “http://localhost:8080/jquery.min.js” was blocked due to MIME type (“”) mismatch (X-Content-Type-Options: nosniff).
websocket
The resource from “http://localhost:8080/sockjs.min.js” was blocked due to MIME type (“”) mismatch (X-Content-Type-Options: nosniff).
websocket
The resource from “http://localhost:8080/script.js” was blocked due to MIME type (“”) mismatch (X-Content-Type-Options: nosniff).
websocket
The resource from “http://localhost:8080/stomp.min.js” was blocked due to MIME type (“”) mismatch (X-Content-Type-Options: nosniff).
websocket
Loading failed for the <script> with source “http://localhost:8080/jquery.min.js”. websocket:7:56
Loading failed for the <script> with source “http://localhost:8080/sockjs.min.js”. websocket:8:56
Loading failed for the <script> with source “http://localhost:8080/stomp.min.js”. websocket:9:55
The resource from “http://localhost:8080/script.js” was blocked due to MIME type (“”) mismatch (X-Content-Type-Options: nosniff).
websocket
Loading failed for the <script> with source “http://localhost:8080/script.js”.

I have spent hours trying to figure out what to do to get around this. I would really appreciate it if someone can shed some light on this issue!

Thanks


Solution

  • First map your static resources properly via WebMvcConfigurer#addResourceHandlers:

    @Configuration(proxyBeanMethods = false)
    public class WebMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry
                    .addResourceHandler("/**")
                    .addResourceLocations("classpath:/static/");
    
            registry.setOrder(1);
        }
    }
    

    Then give the application permission to deliver the required static sources. A simple way to do this is to add the desired endpoint to the SecurityFilterChain:

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    
            http.csrf().disable().authorizeHttpRequests()
    
                    /* allow all static sources placed inside 'webjars' folder */
                    .requestMatchers("/webjars/**").permitAll()
                    /* allow all static sources placed inside 'css' folder */
                    .requestMatchers("/css/**").permitAll()
                    /...
    
                    .requestMatchers("/register").permitAll()
                    .requestMatchers("/websocket").permitAll()
                    .requestMatchers("/home").permitAll().and()
                    .formLogin()
                    .loginPage("/login")
                    .loginProcessingUrl("/login")
                    .defaultSuccessUrl("/websocket", true).permitAll()
                    .and()
                    .logout()
                    .invalidateHttpSession(true)
                    .clearAuthentication(true)
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/login?logout").permitAll();
    
            return http.build();
        }