/api-url has an empty filter list in Spring Boot Security
Asked Answered
A

2

12

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
Aeropause answered 7/4, 2016 at 23:57 Comment(3)
An empty filter list is not an error (you asked it to be ignored). Spring security is not sending the 403. You need to find out where that comes from (maybe inside the registration service itself)?Shadowgraph
@DaveSyer Thank you very much. Can you please suggest how to determine where the message comes from? Perhaps a link? I plan on spending the entire day working on this tomorrow.Aeropause
You already have DEBUG logs for Spring Security so if you don't see it there I don't have any suggestions, sorry. Maybe you should make a simple sample project.Shadowgraph
T
2

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();
        }
Tolan answered 10/4, 2016 at 18:20 Comment(3)
This did not result in getting control flow inside the servlet. Instead, it just labeled the user as ROLE_ANONYMOUS and declined access to the servlet for the reasons shown in 1.) in my ONGOING RESEARCH section shown above in my OP.Aeropause
The only change I made to your code, besides localizing the /url-patterns, was to comment out the one single line: //.antMatchers(actuatorEndpoints()).hasRole(userConfig.getAdminRole())Aeropause
Hi, how did you solve this if you remember? I am facing exactly the same issue.@AeropausePiled
S
2

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).

Shadowgraph answered 10/4, 2016 at 18:23 Comment(3)
These suggestions did not resolve the problem. However, I am pursuing the larger goal by following one of your other code examples.Aeropause
I am approaching this same problem by decomposing an app that you personally developed. Are you willing to take a look at a question I have about it? Here is the link: #36656018Aeropause
This is what was happening in my case. I had a similar problem: I received 403 for a resource that should have been ignored by Spring Security. Turns out there was another problem, which directed to the error page. The error page was not accessible which resulted in the 403. So the error page not being accessible was masking the real problem.Pinhead

© 2022 - 2024 — McMap. All rights reserved.