A Spring Boot app with REST services has to allow public access to certain services, while restricting other services to only authorized users. When a configure(WebSecurity web)
method is added to the SecurityConfig
class as shown below, a 403 error
is sent to the user's web browser, and the Spring Boot log files give an error stating that:
/registration-form has an empty filter list
What specific changes need to be made to the code below to get the /registration-form
service to be successfully served up to any user, including anonymous/un-authenticated users?
Here is the SecurityConfig
class:
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers("/registration-form");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.and()
.httpBasic().and()
.authorizeRequests()
.antMatchers("/login1").permitAll()
.antMatchers("/login2").permitAll()
.anyRequest().authenticated();
}
}
And here is the complete log:
2016-04-07 16:42:18.548 INFO 8937 --- [nio-8001-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2016-04-07 16:42:18.548 INFO 8937 --- [nio-8001-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2016-04-07 16:42:18.656 INFO 8937 --- [nio-8001-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 108 ms
2016-04-07 16:42:18.702 DEBUG 8937 --- [nio-8001-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/registration-form'; against '/css/**'
2016-04-07 16:42:18.702 DEBUG 8937 --- [nio-8001-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/registration-form'; against '/js/**'
2016-04-07 16:42:18.702 DEBUG 8937 --- [nio-8001-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/registration-form'; against '/images/**'
2016-04-07 16:42:18.702 DEBUG 8937 --- [nio-8001-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/registration-form'; against '/**/favicon.ico'
2016-04-07 16:42:18.702 DEBUG 8937 --- [nio-8001-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/registration-form'; against '/error'
2016-04-07 16:42:18.702 DEBUG 8937 --- [nio-8001-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/registration-form'; against '/registration-form'
2016-04-07 16:42:18.702 DEBUG 8937 --- [nio-8001-exec-1] o.s.security.web.FilterChainProxy : /registration-form has an empty filter list
In pom.xml
, the only reference to security is the following:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
I looked around for a version number in pom.xml
, and the closest thing I could find was:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
ONGOING RESEARCH:
1.) This other post gives a good explanation of the difference between WebSecurity
and HttpSecurity
, and thus explains why I included both WebSecurity
and HttpSecurity
in my code shown above.
2.) This 2012 post describes a similar error and solution, but is focused on an old version of Spring Security in general using xml configuration
, and is not specific to Spring Boot with Java Configuration
.
3.) This blog entry explains that old xml config files like web.xml
are largely replaced by the new application.properties
file in Spring Boot. I am therefore not sure whether the solution to the present problem is in adding something application.properties
, or adding some Java Config for Spring Security.
4.) This blog entry describes using the @Bean
annotation to inject a ServletContextInitializer
bean which adds a filter to an end point that was described by @RequestMapping
annotation in a Spring Boot Controller class. The example is a multi-part file filter, but I wonder if this approach could be used to add an appropriate filter to resolve the current OP error message.
5.) This 2014 posting describes two approaches to customizing the behavior of a ServletContextInitializer
in Spring Boot. One approach is to have the Application.java
class extend SpringBootServletInitializer
and then override the configure()
and onStartup()
methods. The other approach shown is to add lines to the application.properties
file using the server
namespace. A list of common properties that can be set in application.properties
is given at this link, but I could not determine which properties to set to resolve the problem defined by the current OP.
6.) @DaveSyer's answer to this related question suggests setting endpoints.info.sensitive=true
in application.properties
to make ALL endpoints open. This got me to find this documentation page from Spring about endpoints, which suggests setting the endpoints.name.sensitive=false
in application.properties
, where name
is the name of the end point being altered. But setting endpoints.api-url.sensitive=false
in application.properties
does not resolve the problem, and eclipse gives a warning that endpoints.api-url.sensitive=false is an unknown property
. Do I have to define the property mapping somewhere else, or perhaps add the /
to make it endpoints./api-url.sensitive=false
? How can I get the correct name to use for the /api-url
endpoint, and is this the correct approach to solving this problem?
7.) I read this other posting, and used its example to create a Filter Registration Bean
inside the main Application
class of the Spring Boot app, but the debug logs still show the same message indicating that the /api-url has an empty filter list
. Here is the code that I added to the Application
class:
@Bean
public FilterRegistrationBean shallowEtagHeaderFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new ShallowEtagHeaderFilter());
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
registration.addUrlPatterns("/api-url");
return registration;
}
The possible approaches from this research include:
1.) adding something to `application.properties`
2.) adding `@Bean` annotation to inject a `ServletContextInitializer`
3.) adding some Spring Security config using Java Configuration.
4.) having Application.java extend SpringBootServletInitializer and
then overriding methods.
5.) adding @Bean annotation to add a filter registration bean
This is what i have where i restrict some URLs and some are public
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(actuatorEndpoints()).hasRole(userConfig.getAdminRole())
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/signup",
"/payment/confirm",
"/api/address/zipcodes/**",
"/user/password/reset",
"/user/password/change",
"/user/email/verify",
"/password/update",
"/email/verify",
"/new-products/**").permitAll()
.antMatchers("/api/**", "/files/**").authenticated();
}
I think what you have done is made the /error view a protected resource. Either open it up or stop using @EnableWebSecurity
(it switches off some stuff that spring boot would have done for you otherwise).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With