0

I'm experience problems loading static resources like images, css styles, etc.... in spring 5 when I add security, without security it load ok

THis is how I done.

First, I create a project using Spring Starter Project in Eclipse Photon

Spring Boot Version: 2.2.6

Add some dependencies:

Spring web

Thymeleaf

Spring Security

Spring Boot DevTools

Spring Boot Actuator

Run the project and I use generated security password and everything ok.

Now I add statics resources

So I create a folder called /assets/imgs

in src/main/resources/static/

I that folder I add a fake image to use in, called fake-image.png

I create a class, with a user and password and patterns to permit my resources.

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
        .authorizeRequests().antMatchers("/resources/**", "/static/**","/src/main/resources/**").permitAll().and()
        .formLogin().loginPage("/login").permitAll()
        .usernameParameter("username").passwordParameter("password")
        .defaultSuccessUrl("/loginsuccess").permitAll().and()
        .logout().permitAll();
    }

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

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder builder) throws Exception {

        PasswordEncoder encoder = passwordEncoder();
        UserBuilder users = User.builder().passwordEncoder(encoder::encode);

        //User to login
        builder.inMemoryAuthentication()
                .withUser(users.username("admin").password("q").roles("ADMIN"));

    }

}

I create a class to add my login form

@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/").setViewName("login");
    }

}

Finally I add a login.html page like this, to show a simple image

<!DOCTYPE html>
<html lang="es" xmlns="http://www.w3.org/1999/xhtml"
    xmlns:th="http://www.thymeleaf.org">
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<meta name="viewport"
    content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="" />
<meta name="author" content="" />

<meta name="ctx" th:content="@{/}" />

<title>Test Static Files</title>

</head>
<body>
    <div class="container">
        <div class="row no-gutters mt-3">
            <div class="col columna-banner">
                <img class="img-fluid rounded login-banner-image"
                    th:src="@{/assets/imgs/fake-image.png}" />
            </div>
        </div>
    </div>
</body>
</html>

In eclipse console I get this warning message:

WARN 1434 --- [nio-8080-exec-2] o.s.web.servlet.PageNotFound : No mapping for GET /assets/imgs/fake-image.png

UPDATE 1:

Added code to github:

https://github.com/davisoski/stackoverflow-static-files

Am I missing something?

Any suggestion?

Thanks

davisoski
  • 727
  • 2
  • 14
  • 41
  • i assume that you created /assets/imgs folder somewhere under /resources, –  Mar 29 '20 at 16:29
  • Yes. Under resources/static – davisoski Mar 29 '20 at 16:34
  • Does [this](https://stackoverflow.com/q/24916894/592355) help? – xerx593 Mar 29 '20 at 17:26
  • Thanks. No. Still not working. I've added code to github – davisoski Mar 29 '20 at 17:33
  • so 1 point is the redirection/path mapping logic your spring version/configuration. By default (current spring), the **url** patterns `/static/*, /public/*, /resources/*` and `/META-INF/*` are *all* mapped to the "classpath (root) of your web application" . By default (current maven/gradle) `src/main/resources` is copied to `/target/classes/` (which is the/one classpath root of your app) ... second/different point is your security config...(but it should align with your links/use case//files/classpath) – xerx593 Mar 29 '20 at 17:36
  • ..leaving everything else/understanding as is, I would give `.authorizeRequests().antMatchers("/assets/**").permitAll()` a try. – xerx593 Mar 29 '20 at 17:38
  • ...and `/src/main/resouces` is not a (real) url ... it is a folder in your development environment, wich will (partially) show up "in web" (mapped to url `/`), because it is a "maven(gradle) default location" – xerx593 Mar 29 '20 at 17:49
  • Added .authorizeRequests().antMatchers("/assets/**").permitAll() at the beginning but no way. I think the code its ok, it related with spring security (I used this code until 1.5.x version of spring boot without problems) – davisoski Mar 29 '20 at 17:59
  • oh yea this(static content handling) changed (significantly but not unfix-able) with spring update... – xerx593 Mar 29 '20 at 18:42

3 Answers3

1

it seems that you forget to add something like this

    @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/static/**")
        .addResourceLocations("classpath:/static/")
        .setCachePeriod(31556926);
}

into your WebConfig class

0

Do you configure the static location in your properties. like spring.resources.static-location=classpath:/static/assets/imgs/

  • Hi. tested 3 options spring.resources.static-locations=classpath:/static/ spring.resources.static-locations=classpath:/static/assets spring.resources.static-locations=classpath:/static/assets/imgs/ – davisoski Mar 29 '20 at 17:21
0

Actually 3 things to know/consider:

  1. Build (maven/gradle)

    Without further configuration all content of sry/main/resources/ folder will be copied into your "classpath root" (classpath:/).

  2. (Url2Class) Path mapping

    Current spring-boot offers/predefines this property:

    (key=)spring.resources.static-locations
    (value=)classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/
    (description=)Locations of static resources. Defaults to classpath:[/META-INF/resources/, /resources/, /static/, /public/].
    

    (Value can be a comma separated list of (classpath) locations.)

    If You are using this is also interesting:

    spring.mvc.static-path-pattern
    /**
    Path pattern used for static resources.
    

    (means: everything from spring.resources.static-locations is mapped against /**, experiment with this and your security config...)

    ..for rather:

    spring.webflux.static-path-pattern
    /**
    Path pattern used for static resources.
    

    So up to this point, it is important to know "where your file lands", and to what url it will be mapped/exposed. Your options with this are:

    1. (preferred) Comply with pre-defined locations.
    2. Override spring.resources.static-locations property.
    3. (least preferred) Introduce a "custom mapping/hadler".
  3. Security config

    Your security config should align with (what you want to allow and with) what url (pattern)s you want to serve. And it is common practice to permit access to static resources.


Regarding OP:

src/main/resources/static/assets/* is available on the class path and (by default) exposed via the url /static/assets/*.

So, please correct in your html file to: th:src="@{/static/assets/imgs/fake-image.png}". (And the 404 more comprehensible, now.)

And then it should work with: .authorizeRequests().antMatchers("/static/**").permitAll().

xerx593
  • 12,237
  • 5
  • 33
  • 64
  • 1
    The links/cites/docs and conclusions refer to the current (2.2.6.RELEASE) spring-boot version, please revise for your version. – xerx593 Mar 29 '20 at 18:57