3

I have 2 Spring Security WebSecurityConfigurerAdapter configs. I want to filter all requests to path /filter1 with filter 1, excluding /filter1/filter2 path. The latter one I want to filter with filter 2. How can I achieve it?

Filter 1 config:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
        .authorizeRequests()
            .antMatchers("filter1/filter2/**").permitAll()
            .and()
        .antMatcher("filter1/**")
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .addFilterBefore(filter1, FilterSecurityInterceptor.class);
}

Filter 2 config:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
        .antMatcher("filter1/filter2/**")
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .addFilterBefore(filter2, FilterSecurityInterceptor.class);
}
dur
  • 15,689
  • 25
  • 79
  • 125
Alvin Mahmudov
  • 103
  • 1
  • 11
  • Did you try something like "filter1/{^(filter2)}/**" for the second filter allowing only authenticated requests? It basically uses regex for filter2, but I am not sure if this is completely supported (though regexes for path variables are supported). – Him Nov 10 '18 at 11:19
  • Why? What do you want to achieve with multiple security filters? – M. Deinum Nov 10 '18 at 12:08
  • @M.Deinum I want to use separate authentications for each url. – Alvin Mahmudov Nov 10 '18 at 12:15
  • @Him it is not working – Alvin Mahmudov Nov 10 '18 at 12:15
  • If that is what you want you don't need separate filters for that. Start with an `antMatcher` that matches the path and configure it. – M. Deinum Nov 10 '18 at 12:23
  • You are suggesting to combine 2 auth mechanisms in 1 filter? – Alvin Mahmudov Nov 10 '18 at 12:29
  • @AlvinMahmudov: What is the order of your configuations? The fist one has to be before the second configuration. Show your classes with annotations. – dur Nov 10 '18 at 18:35
  • Possible duplicate of https://stackoverflow.com/questions/33603156/spring-security-multiple-http-config-not-working – dur Nov 10 '18 at 18:36

1 Answers1

-2

Just write a single configuration, ordering the urls in the way they should match (ordering is important here!).

Something like the following

http
  .csrf().disable()
  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  .and()
        .authorizeRequests().anyRequest().authenticated()
   .and()
        .antMatcher("filter1/filter2/**")
        .addFilterBefore(filter2, FilterSecurityInterceptor.class)
        .antMatcher("filter1/**")
        .addFilterBefore(filter1, FilterSecurityInterceptor.class);

Should do that. It will match the most specific one and use that filter chain. Not sure if you need to move the .authorizeRequests().anyRequest().authenticated() to each mapping as well.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • The only thing is, I don't need filter1 to be triggered if filter2 has been triggered. – Alvin Mahmudov Nov 10 '18 at 12:39
  • It doesn't. It will match the specific one. The first chain that matches will be executed. Hence ordering is important here. – M. Deinum Nov 10 '18 at 12:49
  • I just tested and both filters get called. First filter2 then filter1. Even if the path doesn't match. Maybe that is because the filters are defined as spring beans. – Alvin Mahmudov Nov 10 '18 at 12:57
  • They get called because they are part of the normal filter chain and not just the security filter chain. Add an additional `FilterRegistrationBean` and disable the filter with that (setting the `enabled` property to `false`) to prevent them from being registered in the regular filter chain. – M. Deinum Nov 10 '18 at 12:59
  • 1
    ` @Bean public FilterRegistrationBean filterRegistration(SecurityFilter filter2) { FilterRegistrationBean registration = new FilterRegistrationBean(filter2); registration.setEnabled(false); return registration; } @Bean public FilterRegistrationBean filterRegistration2(SecurityFilter filter1) { FilterRegistrationBean registration = new FilterRegistrationBean(filter1); registration.setEnabled(false); return registration; } ` I already have.They are called only when I am accessing filter1 or filter2 paths. – Alvin Mahmudov Nov 10 '18 at 13:02
  • Weird, that shouldn't happen (AFAIK). Do you have an accidental `@WebFilter` or some additional double instance of the filter? You can enable debug logging for Spring Security and see what is happening in there. – M. Deinum Nov 10 '18 at 13:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/183416/discussion-between-alvin-mahmudov-and-m-deinum). – Alvin Mahmudov Nov 10 '18 at 13:06
  • 1
    @M.Deinum I would say, your answer is wrong. See my answer of another question https://stackoverflow.com/a/39465718/5277820. Do you agree? – dur Nov 10 '18 at 18:44