Serving static web resources in Spring Boot & Spring Security application

ghz 1years ago ⋅ 684 views

Question

I am trying to develop Spring Boot web application and securing it using Spring security java configuration.

After placing my static web resources in ' src/main/resources/public ' as advised [here in Spring blog](http://spring.io/blog/2013/12/19/serving-static- web-content-with-spring-boot), I am able to get the static resources. i.e hitting https://localhost/test.html in browser do serves the html content.

Problem

After I enabled Spring Security, hitting the static resource URL requires authentication.

My relevent Spring Security Java config looks like this:-

@Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.
            authorizeRequests()
                .antMatchers("/","/public/**", "/resources/**","/resources/public/**")
                    .permitAll()
                .antMatchers("/google_oauth2_login").anonymous()
                    .anyRequest().authenticated()
                .and()
                .formLogin()
                    .loginPage("/")
                    .loginProcessingUrl("/login")
                    .defaultSuccessUrl("/home")
                    .and()
                    .csrf().disable()
                    .logout()
                        .logoutSuccessUrl("/")
                        .logoutUrl("/logout") // POST only
                .and()
                    .requiresChannel()
                    .anyRequest().requiresSecure()
                .and()
                    .addFilterAfter(oAuth2ClientContextFilter(),ExceptionTranslationFilter.class)
                    .addFilterAfter(googleOAuth2Filter(),OAuth2ClientContextFilter.class)
                .userDetailsService(userService);
        // @formatter:on
    }

How should I configure antMatchers to permit static resources placed inside src/main/resources/public ?


Answer

There are a couple of things to be aware of:

  • The Ant matchers match against the request path and not the path of the resource on the filesystem.
  • Resources placed in src/main/resources/public will be served from the root of your application. For example src/main/resources/public/hello.jpg would be served from http://localhost:8080/hello.jpg

This is why your current matcher configuration hasn't permitted access to the static resources. For /resources/** to work, you would have to place the resources in src/main/resources/public/resources and access them at http://localhost:8080/resources/your-resource.

As you're using Spring Boot, you may want to consider using its defaults rather than adding extra configuration. Spring Boot will, by default, permit access to /css/**, /js/**, /images/**, and /**/favicon.ico. You could, for example, have a file named src/main/resources/public/images/hello.jpg and, without adding any extra configuration, it would be accessible at http://localhost:8080/images/hello.jpg without having to log in. You can see this in action in the [web method security smoke test](https://github.com/spring-projects/spring- boot/tree/df58a5b5576494d5968019a71b20619e3777da63/spring-boot-tests/spring- boot-smoke-tests/spring-boot-smoke-test-web-method-security) where access is permitted to the Bootstrap CSS file without any special configuration.