Search code examples
javaspring-bootspring-securityhttp-deletex-content-type-options

Resource blocked due to MIME type in Spring MVC when DELETE endpoint added


I'm developing a web app using Spring Boot v2.1.9.RELEASE and Thymeleaf. The app mixes server-side rendering (Spring MVC regular controllers) with rest controllers called through AJAX. The page works like a charm as long as GET and POST are the only HTTP methods I use. As soon as I add a - totally unrelated, yet unused - DELETE REST controller, CSS and JS resources stop being loaded and errors like the following are shown in browser console:

The resource from “http://localhost:8080/css/demo.css” was blocked due to MIME type (“application/json”) mismatch (X-Content-Type-Options: nosniff)

If I remove the new controller, the page starts working again.

When I inspect the request with Network Monitor, I observe that:

  • X-Content-Type-Options: nosniff header is always present in the response, which is consistent with Spring Security documentation.
  • if the DELETE endpoint is not there, a GET /css/demo.css request returns with a HTTP 200 code as expected. Both Accept (request header) and Content-Type (response header) are marked as text/css.
  • when I add the endpoint, the above request returns a HTTP 405. Accept header is text/css but Content-Type becomes application/json. Also, a new response header is added: Allow: DELETE.

My guess is that when Spring scans for controllers and a DELETE method is found, some extra configuration is automatically added, but I couldn't find any reference to confirm that. I would like to know why is this happening and how can I avoid this behaviour.

Since I'm developing local, my Spring Security config is pretty straightforward:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public AuthenticationManagerConfigurer authConfigurer() {
        return new InMemoryAuthenticationManagerConfigurer();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        authConfigurer().configure(auth);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin();
    }

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

The REST controller I'm adding does almost nothing:

@RestController
public class MotivosController {

    private final String CONTROLLER_PATH = "/rest/motivos/{id}";

    @RequestMapping(name=CONTROLLER_PATH, method=RequestMethod.DELETE)
    public void deleteMotivo(@PathVariable(name="id") String id) {
        logger.debug("Eliminando el motivo " + id);
    }

    // Other members I consider unrelated to the problem go here...
}

CSS and JS files are being loaded in a template.html file placed under src/main/resources/templates folder, as follows:

<link type="text/css" href="/css/demo.css" rel="stylesheet" />


Solution

  • Answer was easier than I thought and I was totally wrong with my assumptions. I confused @RequestMapping's name attribute with value attribute, and because of that any URL matches that method. Changing name for value made it work.