Reputation: 379
So I have a working frontend with Angular2 and a working backend with Java and what I do is to serve my index.html from the static folder which also contains all my frontend resources. The problem is that when I tried to add Spring Security to the backend the resources are not accessible anymore because of the @EnableWebSecurity annotation. When I navigate to my localhost http://localhost:8080/ the index.html is not served. But if I access it or any other resource writing the path manually, it loads. I wouldn't like to serve my frontend differently, is there any way to do this from the static? I tried the following:
Here my security configuration:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan(basePackages = {"com.ramso.restapi.security"})
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
public static final String REMEMBER_ME_KEY = "rememberme_key";
public SecurityConfig() {
super();
logger.info("loading SecurityConfig ................................................ ");
}
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private RestUnauthorizedEntryPoint restAuthenticationEntryPoint;
@Autowired
private AuthenticationSuccessHandler restAuthenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler restAuthenticationFailureHandler;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/front/**","/index.html");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers("/failure").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/authenticate")
.successHandler(restAuthenticationSuccessHandler)
.failureHandler(restAuthenticationFailureHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
.deleteCookies("JSESSIONID")
.permitAll()
.and();
}
}
WebMvcConfiguration:
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//registry.addViewController("/").setViewName("front/index.html");
//registry.addViewController("/").setViewName("forward:/index.html");
registry.addViewController("/").setViewName("redirect:/index.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
Application.java:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Upvotes: 4
Views: 5351
Reputation: 3850
In the class that extends WebSecurityConfigurerAdapter
you can add the following:
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/front/**");
}
Any ant matcher you put in web.ignoring()
method should be ignored by spring security.
By default the static content should be placed in one of the following directories under src/main/resources
(from spring boot - static content):
/META-INF/resources/
/resources/
/static/
/public/
Then any ant matcher is checked in front of the sub folders.
For example, if your static content is in src/main/resources/static/front
the ant matcher /front/**
should ignore all resources in that sub-folder.
Also, in order to expose index.html
you should place it in src/main/resources/static
and add something like the following class in order to expose it as the main resource when accessing your site:
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
and of course add it as an ant matcher: web.ignoring().antMatchers("/*", "/front/**", "index.html");
/*
will not allow all, /**
does that. make sure you place your API's on a secure endpoint like /api
or something like that and the static content on an ignored path.
Upvotes: 7
Reputation: 7682
The problem could be that angular-cli puts all resources at the root of your app. (Though I'm not sure you are using angular-cli)
But lets entertain the notion.
angular-cli outputs something like
/inline.8faab088ca0e1cca9031.bundle.js
/main.c7b67df9d7c42383815c.bundle.js
/polyfills.c234d2c8820869e3c698.bundle.js
/styles.d41d8cd98f00b204e980.bundle.css
/vendor.f0f36dacdf3fba21c295.bundle.js
This makes it very hard for you to apply a spring security antMatcher.
angular-cli has a configuration called --deploy-url=/ui/
which will mean that all script files point to a directory called /ui/
<script type="text/javascript" src="/ui/inline.4c30f42211c1d30d3dd3.bundle.js"></script>
<script type="text/javascript" src="/ui/polyfills.c234d2c8820869e3c698.bundle.js"></script>
<script type="text/javascript" src="/ui/vendor.f0f36dacdf3fba21c295.bundle.js"></script>
<script type="text/javascript" src="/ui/main.c7b67df9d7c42383815c.bundle.js"></script>
Then you should be able to ignore the path as Tom suggests.
Upvotes: 1