1

I have built a basic spring authentication service from this source: https://spring.io/guides/gs/securing-web/

Tried to include JS files from Local folders using almost all solutions on stackoverflow but I couldn't. When the html page loads, it says:
"Uncaught ReferenceError: myFunction is not defined"

Here is my home.html script:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example</title>
        <script type="javascript" src="test.js"></script>
    </head>
    <body onload="myFunction()">
        <h1>Welcome!</h1>

        <p>Click <a href="/hello">here</a> to see a greeting.</p>
    </body>
</html>

Here is where my js file is located and htmls are placed in templates folder.

enter image description here

here is my mvcConfig code:

package hello;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;


@Configuration
public class MvcConfig implements WebMvcConfigurer {

    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/home").setViewName("home");
        registry.addViewController("/").setViewName("home");
        registry.addViewController("/hello").setViewName("redirect:http://localhost:3000/home.html");
        registry.addViewController("/login").setViewName("login");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!registry.hasMappingForPattern("/webjars/**")) {
        registry.addResourceHandler("/webjars/**").addResourceLocations(
                "classpath:/META-INF/resources/webjars/");
    }
    if (!registry.hasMappingForPattern("/**")) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/", "classpath:/resources/","classpath:/static/", "classpath:/public/");
    }

    registry.addResourceHandler("/resources/**")
        .addResourceLocations("/resources/");


}

}

WebSecurityConfig code:

package hello;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home","/resources/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

@Bean
@Override
public UserDetailsService userDetailsService() {
    UserDetails user =
         User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();

    return new InMemoryUserDetailsManager(user);
}

}

Ajay Venkata Raju
  • 1,098
  • 12
  • 22

2 Answers2

1

Whatever the folder are in src/main/resources ,you can configure them like this ,Create this method in your security config class,generally we put static resources in static folder inside src/main/resources.

//this method allows static resources to be neglected by spring security
        @Override
        public void configure(WebSecurity web) throws Exception {
            web
                .ignoring()
                .antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/assets/**","/fonts/**","/dis/**","/vendor1/**");
        }
Shubham Dixit
  • 9,242
  • 4
  • 27
  • 46
1

In the WebSecurityConfig class you set permitAll to only '/', '/home', and '/resources/**'. An anonymous user can access these three endpoints without security check.

For test.js file, the src points to test.js in the current url. So when you run it on localhost, the browser tries to find the test.js as http://localhost:{port}/{current-page-url}/test.js

For example, if the page is under /home then the browser calls http://localhost:8080/home/test.js, but as you defined in the WebSecurityConfig any call except /home itself will be blocked by Spring Security. (/home is not the same as /home/**)

So what you need to do is to change the src url to <script src="/resources/test.js"></script> Because anything under the /resources/** endpoint can be accessed by anyone and it is already registered in the resourceHandler configuration in the MvcConfig

    registry.addResourceHandler("/resources/**")
    .addResourceLocations("classpath:/");

Hope this helps! Happy Coding :)

ADD :

Also the in the <script> tag you should change the type attribute to text/javascript or you can just remove the attribute and it will work.

john koo
  • 221
  • 1
  • 4
  • I already tried this solution but it didn't worked.. let me try again and confirm – Ajay Venkata Raju Sep 28 '18 at 07:27
  • 1
    don't forget to add `/` at the beginning to point to the classpath – john koo Sep 28 '18 at 07:29
  • Not working.. it says :

    Whitelabel Error Page

    This application has no explicit mapping for /error, so you are seeing this as a fallback.

    Fri Sep 28 12:58:49 IST 2018
    There was an unexpected error (type=Internal Server Error, status=500).
    An error happened during template parsing (template: "class path resource [templates/home.html]" - line 5, col 3)
    – Ajay Venkata Raju Sep 28 '18 at 07:38
  • 1
    Ajay if the `test.js` file is in the resources folder then you should point the resourceLocation as `.addResourceLocations("classpath:/")` or as Jai mentioned you can put all static files in the /resources/static folder to organize them and `.addResourceLocations("classpath:/static")` – john koo Sep 28 '18 at 08:44
  • Thank you koo.. updating this has solved half of my issue. registry.addResourceHandler("/**") .addResourceLocations("classpath:/"); – Ajay Venkata Raju Sep 28 '18 at 11:45
  • Good. Now it seems the `test.js` is loaded but `myFunction()` is not found right? What you can do is to change the type to ` – john koo Sep 28 '18 at 14:15