Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring webSecurity.ignoring() doesn't ignore custom filter

I have a set a custom authentication filter in my Spring 4 MVC + Security + Boot project. The filter does it's job well and now I want to disable the security for some URI (like /api/**). Here is my configuration:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity.ignoring().antMatchers("/api/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests()
                 .anyRequest().authenticated()
              .and()
                 .addFilterBefore(filter, BasicAuthenticationFilter.class);
    }
}

Unfortunately, when I call a resource under /api/... the filter is still chained. I've added println in my filter and it's written to the console on every call. Do you know what's wrong with my configuration?

UPDATE

Filter code:

@Component
public class EAccessAuthenticationFilter extends RequestHeaderAuthenticationFilter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("FILTER");
        if(SecurityContextHolder.getContext().getAuthentication() == null){
            //Do my authentication stuff
            PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(user, credential, authorities);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }  
        super.doFilter(request, response, chain);
     }

    @Override
    @Autowired
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }

}
like image 847
rattek Avatar asked Aug 25 '16 18:08

rattek


3 Answers

remove @Component on class EAccessAuthenticationFilter,and like this:

@Override
protected void configure(HttpSecurity http) throws Exception {
   http.authorizeRequests()
             .anyRequest().authenticated()
          .and()
             .addFilterBefore(new EAccessAuthenticationFilter(), BasicAuthenticationFilter.class);
}

https://github.com/spring-projects/spring-security/issues/3958

like image 58
kimhom Avatar answered Nov 02 '22 13:11

kimhom


I don't have enough reputation to add a comment, but for anyone like me who was looking for a little more of an explanation for kimhom's answer, WebSecurityConfigurerAdapter will tell Spring Security to ignore any filters added through it. The filter was then still being invoked because the @Component (or any flavor of @Bean) annotation told Spring to add the filter (again) outside of the security chain. So while the filter was being ignored in the security chain, it was not being ignored by the other (non-security?) chain.

This solved two weeks of headaches for me. In my case my custom filter needed the Authentication object given by the SecurityContext where it kept coming up as null because the security chain was never executed.

like image 25
lancekf Avatar answered Nov 02 '22 14:11

lancekf


I had the correct configuration to ignore some context path in the web security configuration as below..

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/v1/api1").antMatchers("/v1/api2");
}

But I mistakenly had added @PreAuthorize(...) on my controller method and it seems like that method level security was overriding any security configuration set up at the start.

like image 2
Prashant Rajput Avatar answered Nov 02 '22 13:11

Prashant Rajput