title: Spring Boot returns login page instead of styles
body: <p>I have a Spring Boot app and for some reason each request from client to <code>css</code> files receives HTML of login page in response. No error, no redirect, status is 200 and HTML is in response body. What can be the reason of it?</p>
  
  <p>Login page:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml" lang="en" xmlns:th="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
      &lt;meta charset="UTF-8"&gt;
      &lt;title&gt;Sign in&lt;/title&gt;
      &lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
            integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"&gt;
      &lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
            integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"&gt;
      &lt;link th:href="@{/css/login.css}" rel="stylesheet" media="screen"/&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;div class="input-group outlet"&gt;
      &lt;p&gt;Sign in&lt;/p&gt;
      &lt;form th:action="@{/login}" method="post"&gt;
          &lt;div&gt;&lt;input name="username"/&gt;&lt;/div&gt;
          &lt;div&gt;&lt;input name="password" type="password"/&gt;&lt;/div&gt;
          &lt;div&gt;
              &lt;button type="submit"&gt;Login&lt;/button&gt;
          &lt;/div&gt;
          &lt;div th:if="${loginError}"&gt;&lt;p&gt;Invalid username or password&lt;/p&gt;&lt;/div&gt;
      &lt;/form&gt;
  &lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>Security config:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
      @Autowired
      private PasswordEncoder passwordEncoder;
  
      //TODO: fix this
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
                  .authorizeRequests()
                      .antMatchers("/resources/**", "/css/**").permitAll()
                      .anyRequest().authenticated()
                  .and()
                  .formLogin()
                      .loginPage("/login")
                      .defaultSuccessUrl("/welcome")
                      .failureUrl("/login-error")
                      .permitAll();
      }
  
      @Autowired
      public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth
                  .inMemoryAuthentication()
                  .passwordEncoder(passwordEncoder)
                  .withUser("user").password("password").roles("USER");
      }
  
      @Bean
      PasswordEncoder passwordEncoder() {
          return NoOpPasswordEncoder.getInstance();
      }
  }
  </code></pre>
  
  <p>Login controller:</p>
  
  <pre><code>@Controller("login")
  public class LoginController {
      @GetMapping
      public String login() {
          return "login";
      }
  
      @PostMapping
      public String postLogin() {
          // TODO
          return "/welcome";
      }
  
      @GetMapping("/login-error")
      public String loginError(Model model) {
          model.addAttribute("loginError", true);
          return "login";
      }
  }
  </code></pre>
  
  <p>Response headers:</p>
  
  <pre><code>Cache-Control:no-cache, no-store, max-age=0, must-revalidate
  Content-Language:en-US
  Content-Type:text/css;charset=UTF-8
  Date:Thu, 23 Nov 2017 17:17:59 GMT
  Expires:0
  Pragma:no-cache
  Transfer-Encoding:chunked
  X-Content-Type-Options:nosniff
  X-Frame-Options:DENY
  X-XSS-Protection:1; mode=block
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/gznLh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/gznLh.png" alt="Folder structure:"></a></p>
  
  <p><strong>UPD:</strong>
  An important thing to notice is that if I don't explisitly use permitAll() on /css/**, then I get 302 and redirect to login page. If I do, then I get 200 and content of login page in response body instead of actual content of css file</p>
  
  <p><strong>UPD 2:</strong>
  Debug logs from spring security during request to login page, which should have the styles:</p>
  
  <pre><code>2017-11-24 17:43:33.926 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
  2017-11-24 17:43:33.927 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
  2017-11-24 17:43:33.938 DEBUG 4088 --- [io-1488-exec-10] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
  2017-11-24 17:43:33.938 DEBUG 4088 --- [io-1488-exec-10] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
  2017-11-24 17:43:33.941 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
  2017-11-24 17:43:33.942 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@f14213c
  2017-11-24 17:43:33.942 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
  2017-11-24 17:43:33.943 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
  2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login' doesn't match 'POST /logout
  2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
  2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login' doesn't match 'POST /login
  2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
  2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
  2017-11-24 17:43:33.946 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
  2017-11-24 17:43:33.947 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.AnonymousAuthenticationFilter  : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
  2017-11-24 17:43:33.947 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
  2017-11-24 17:43:33.947 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.session.SessionManagementFilter  : Requested session ID 3A4BF8C25F0B7B63F9906222B94C800A is invalid.
  2017-11-24 17:43:33.948 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
  2017-11-24 17:43:33.948 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
  2017-11-24 17:43:33.950 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /login; Attributes: [permitAll]
  2017-11-24 17:43:33.955 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
  2017-11-24 17:43:33.963 DEBUG 4088 --- [io-1488-exec-10] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@7f46f895, returned: 1
  2017-11-24 17:43:33.963 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorization successful
  2017-11-24 17:43:33.963 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor    : RunAsManager did not change Authentication object
  2017-11-24 17:43:33.963 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy        : /login reached end of additional filter chain; proceeding with original chain
  2017-11-24 17:43:34.826 DEBUG 4088 --- [io-1488-exec-10] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
  2017-11-24 17:43:34.862 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
  2017-11-24 17:43:34.862 DEBUG 4088 --- [io-1488-exec-10] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
  2017-11-24 17:43:35.015 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
  2017-11-24 17:43:35.015 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
  2017-11-24 17:43:35.015 DEBUG 4088 --- [nio-1488-exec-9] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
  2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@7582e3b6. A new one will be created.
  2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
  2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@f14213c
  2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
  2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
  2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /css/login.css' doesn't match 'POST /logout
  2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
  2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /css/login.css' doesn't match 'POST /login
  2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
  2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
  2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
  2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.AnonymousAuthenticationFilter  : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@6fa8940c: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: EACE11EC21F40FE5BD10CC56F71C0DD3; Granted Authorities: ROLE_ANONYMOUS'
  2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
  2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
  2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
  2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/css/login.css'; against '/css/**'
  2017-11-24 17:43:35.019 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /css/login.css; Attributes: [permitAll]
  2017-11-24 17:43:35.019 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@6fa8940c: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: EACE11EC21F40FE5BD10CC56F71C0DD3; Granted Authorities: ROLE_ANONYMOUS
  2017-11-24 17:43:35.021 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@7f46f895, returned: 1
  2017-11-24 17:43:35.021 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorization successful
  2017-11-24 17:43:35.021 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.i.FilterSecurityInterceptor    : RunAsManager did not change Authentication object
  2017-11-24 17:43:35.021 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy        : /css/login.css reached end of additional filter chain; proceeding with original chain
  2017-11-24 17:43:35.031 DEBUG 4088 --- [nio-1488-exec-9] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
  2017-11-24 17:43:35.033 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
  2017-11-24 17:43:35.033 DEBUG 4088 --- [nio-1488-exec-9] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
  </code></pre>
  
  <p><strong>UPD 3:</strong>
  Debug logs of MVC seem fishy, why does it map the request to <code>login.css</code> to my login controller?</p>
  
  <pre><code>2017-11-24 19:05:13.967 DEBUG 27408 --- [nio-1488-exec-9] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/css/login.css]
  2017-11-24 19:05:13.967 DEBUG 27408 --- [nio-1488-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /css/login.css
  2017-11-24 19:05:13.968 DEBUG 27408 --- [nio-1488-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.lang.String zhi.yest.furniture.controller.LoginController.login()]
  2017-11-24 19:05:13.968 DEBUG 27408 --- [nio-1488-exec-9] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/css/login.css] is: -1
  2017-11-24 19:05:13.969 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/css] based on Accept header types and producible media types [*/*])
  2017-11-24 19:05:13.969 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.servlet.view.BeanNameViewResolver  : Found matching bean for view name 'login' - to be ignored since it does not implement View
  2017-11-24 19:05:13.969 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.servlet.view.BeanNameViewResolver  : No matching bean found for view name 'login.css'
  2017-11-24 19:05:13.970 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.s.v.ContentNegotiatingViewResolver : No acceptable view found; returning null
  2017-11-24 19:05:13.970 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.servlet.view.BeanNameViewResolver  : Found matching bean for view name 'login' - to be ignored since it does not implement View
  2017-11-24 19:05:13.970 DEBUG 27408 --- [nio-1488-exec-9] o.s.web.servlet.DispatcherServlet        : Rendering view [org.thymeleaf.spring4.view.ThymeleafView@6cb35f4f] in DispatcherServlet with name 'dispatcherServlet'
  2017-11-24 19:05:13.979 DEBUG 27408 --- [nio-1488-exec-9] o.s.web.servlet.DispatcherServlet        : Successfully completed request
  </code></pre>