Serving static web resources in Spring Boot & Spring Security application

spring boot static resources path
spring boot 2 static resources
spring boot serve static content from file system
spring boot static content 404
spring 4 mvc:resources
spring security static resources
spring boot serve spa
spring boot static resource webapp

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, 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 ?

Serving Static Web Content with Spring Boot, How to map and handle static resources with Spring MVC - use the For example, if we put an about.html file inside the /static directory in our  Spring Boot will automatically add static web resources located within any of the following directories: /META-INF/resources/ /resources/ /static/ /public/ In the case of the Consuming a RESTful Web Service with jQuery guide, we included index.html and hello.js files in the /public/ folder. This means that not only does Spring Boot offer a simple approach to building Java or Groovy apps, you can also use it to easily deploy client-side JavaScript code and test it within a real web server

  @Override
      public void configure(WebSecurity web) throws Exception {
        web
          .ignoring()
             .antMatchers("/resources/**"); // #3
      }

Ignore any request that starts with "/resources/". This is similar to configuring http@security=none when using the XML namespace configuration.

Serve Static Resources with Spring, Spring Boot automatically adds static web resources located within any of the following directories: /META-INF/resources/; /resources/; /static/  By default Spring boot serves static content from one of the following locations in the classpath: /static /public /resources /META-INF/resources; Example. For a maven project, the content of src/main/resources/ is in classpath during runtime, so we will be adding above locations there.

Here is the ultimate solution, after 20+ hours of research.

Step 1. Add 'MvcConfig.java' to your project.

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
                .addResourceHandler("/resources/**")
                .addResourceLocations("/resources/");
    }
}

Step 2. Add configure(WebSecurity web) override to your SecurityConfig class

@Override
    public void configure(WebSecurity web) throws Exception {
        web
                .ignoring()
                .antMatchers("/resources/**");
    }

Step 3. Place all static resources in webapp/resources/..

Spring Boot static content, We can customize the static resource locations using spring.resources.static-​locations property. That will replace the default values with a list of  Spring Boot automatically adds static web resources located within any of the following directories: /META-INF/resources/ /resources/ /static/ /public/ The directories are located in the classpath or in the root of the ServletContext. In our application, we have one HTML file which contains a simple link.

This may be an answer (for spring boot 2) and a question at the same time. It seems that in spring boot 2 combined with spring security everything (means every route/antmatcher) is protected by default if you use an individual security mechanism extended from

WebSecurityConfigurerAdapter

If you don´t use an individual security mechanism, everything is as it was?

In older spring boot versions (1.5 and below) as Andy Wilkinson states in his above answer places like public/** or static/** are permitted by default.

So to sum this question/answer up - if you are using spring boot 2 with spring security and have an individual security mechanism you have to exclusivley permit access to static contents placed on any route. Like so:

@Configuration
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {

private final ThdAuthenticationProvider thdAuthenticationProvider;

private final ThdAuthenticationDetails thdAuthenticationDetails;

/**
 * Overloaded constructor.
 * Builds up the needed dependencies.
 *
 * @param thdAuthenticationProvider a given authentication provider
 * @param thdAuthenticationDetails  given authentication details
 */
@Autowired
public SpringSecurityConfiguration(@NonNull ThdAuthenticationProvider thdAuthenticationProvider,
                                   @NonNull ThdAuthenticationDetails thdAuthenticationDetails) {
    this.thdAuthenticationProvider = thdAuthenticationProvider;
    this.thdAuthenticationDetails = thdAuthenticationDetails;
}

/**
 * Creates the AuthenticationManager with the given values.
 *
 * @param auth the AuthenticationManagerBuilder
 */
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {

    auth.authenticationProvider(thdAuthenticationProvider);
}

/**
 * Configures the http Security.
 *
 * @param http HttpSecurity
 * @throws Exception a given exception
 */
@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
            .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
            .antMatchers("/management/**").hasAnyAuthority(Role.Role_Engineer.getValue(),
            Role.Role_Admin.getValue())
            .antMatchers("/settings/**").hasAnyAuthority(Role.Role_Engineer.getValue(),
            Role.Role_Admin.getValue())

            .anyRequest()
            .fullyAuthenticated()
            .and()
            .formLogin()
            .authenticationDetailsSource(thdAuthenticationDetails)
            .loginPage("/login").permitAll()
            .defaultSuccessUrl("/bundle/index", true)
            .failureUrl("/denied")
            .and()
            .logout()
            .invalidateHttpSession(true)
            .logoutSuccessUrl("/login")
            .logoutUrl("/logout")
            .and()
            .exceptionHandling()
            .accessDeniedHandler(new CustomAccessDeniedHandler());
}

}

Please mind this line of code, which is new:

.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()

If you use spring boot 1.5 and below you don´t need to permit these locations (static/public/webjars etc.) explicitly.

Here is the official note, what has changed in the new security framework as to old versions of itself:

Security changes in Spring Boot 2.0 M4

I hope this helps someone. Thank you! Have a nice day!

Spring Boot - Serving static web contents, This tutorial will teach you how to configure Spring Boot so serve static resources (HTML, css, javascript) in your Web applications. Spring Boot comes with a pre-configured implementation of  ResourceHttpRequestHandler   to facilitate serving static resources. By default, this handler serves static content from any of  /static, /public, /resources,  and  /META-INF/resources  directories that are on the classpath.

If you are using webjars. You need to add this in your configure method: http.authorizeRequests().antMatchers("/webjars/**").permitAll();

Make sure this is the first statement. For example:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/webjars/**").permitAll();
        http.authorizeRequests().anyRequest().authenticated();
         http.formLogin()
         .loginPage("/login")
         .failureUrl("/login?error")
         .usernameParameter("email")
         .permitAll()
         .and()
         .logout()
         .logoutUrl("/logout")
         .deleteCookies("remember-me")
         .logoutSuccessUrl("/")
         .permitAll()
         .and()
         .rememberMe();
    }

You will also need to have this in order to have webjars enabled:

@Configuration
    public class MvcConfig extends WebMvcConfigurerAdapter {
        ...
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        }
        ...
    }

Serving static content in Spring Boot applications, Spring Boot automatically picks the static resources from src/main/resources/ location to be served as web page. You can get this running in 5 minutes. If you like it  I am trying to add static web content in a spring-boot server using the info here I have tried adding the .js and .css files I need in the several Folders that the previous link says but it doesn'

Spring Boot Web App serving static HTML page, Any static content such as image, .html file, JS or CSS file can be By default, Spring Boot serves static content from /public , /static , /resources  Static resources, including HTML and JavaScript and CSS, can be served from your Spring Boot application by dropping them into the right place in the source code. By default, Spring Boot serves static content from resources in the classpath at /static (or /public).

Serving Static Content with Spring Cloud Gateway, In this tutorial we show how Spring Boot serves static resources like (html, js, css) in a web application. 1- Default path for static resources. By default Spring Boot will serve static content from a folder called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext. You can also compare your project with the guide Serving Web Content with Spring MVC, or check out the source code of the spring-boot-sample-web-ui project.

Serve Static Resources with Spring Boot, springboot-Quick guide to serve static HTML page and bootstrap the css and js files to this project's src/main/resources/static,just like this:. Static web resources versioning is a central concern when pushing web apps to production and very much a server-side concern. Spring Framework 4.1 aims to provide first class support through various strategies including content-based hashing (like in Git, also known as fingerprinting) as well as versions that apply to entire sets of files (e.g

Comments
  • See also stackoverflow.com/questions/24164014/…
  • src/main/resources/public !
  • - I've cloned the spring boot sample repo and run the example ( web method security sample). It is not working. localhost:8080/css/bootstrap.min.css is redirected to login page. - It is different implemented as described solution. Static file has path: src/main/resources/static/css/
  • See the answer of Thomas Lang if you are using Spring Boot 2
  • static or css js should be inside src/main/resources/public here public folder is the key. Thanks
  • Does not work for me, either. While I'm loading my static html from an API, and refer to one of my static files at /resources/css/main.css. The html page rendered by Rest API works fine. However, static css does not.
  • Could you explain what are you doing and why? "Step1": add static resource handling. "Step2": remove static resource handling.
  • If someone uses XML configuration then in step 1 you can use this line <mvc:resources mapping="/resources/**" location="/resources/" /> in your dispatcher-servlet.xml instead of creating new Java config class.
  • I can confirm that adding the extra line fixed it for me (Spring Boot 2.0.3)
  • Extra line does help a lot but I need to add few more lines to make it working. Boot version 2.0.6. (1) .antMatchers("/", "/callback", "/login**", "/webjars/**", "/error**", "/static/**").permitAll() and (2) registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); under WebMvcConfigurer.addResourceHandlers().
  • Thank you so much for this!
  • Will calling super.configure not enable Basic Auth?
  • For the ones wanting most resources: http.authorizeRequests().antMatchers(HttpMethod.GET, "/", "/index.html", "/favicon.ico", "/**/*.js", "/**/*.js.map", "/**/*.css", "/assets/images/*.png", "/assets/images/*.jpg", "/assets/images/*.jpeg", "/assets/images/*.gif", "/**/*.ttf", "/**/*.json", "/**/*.woff", "/**/*.woff2", "/**/*.eot", "/**/*.svg").permitAll() If you're wondering why double ** . With ** it means permit anywhere where there is a file with that extension. Also NOTE the HTTPMETHOD.GET. Replace /assets/images with your own folder. Otherwise just put /*.jpg