Home > Net >  SecurityConfiguration / RequestMatcher issue with several AntPathRequestMatcher
SecurityConfiguration / RequestMatcher issue with several AntPathRequestMatcher

Time:10-07

I just added token authentication to my spring boot API and it's working well, with only one issue.

I want to use the /login endpoint (with login and password) to get a token, which be then passed in the header to all services requiring authentication, namely logout and everything on the /api/** routes.

My issue is that I have to leave /login unprotected but not the logout one however I can't remove the line marked // TODO Why can't I remove this in the following code or I get a 403 error (Forbidden) when accessing /logout with or without token

And I don't get why, I think it's related maybe to my RequestMacther :

private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
            new AntPathRequestMatcher("/api/**"),
            new AntPathRequestMatcher("/logout/**")
    );

However the /logout does indeed requires authentication with token, so maybe it's not that.

TLDR everything is working well with this code but I'd like to remove the line after // TODO Why can't I remove this but I get a 403 on /logout if I do remove it

Any help appreciated.

My SecurityConfiguration :

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@AllArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
            new AntPathRequestMatcher("/api/**"),
            new AntPathRequestMatcher("/logout/**")
    );

    AuthenticationProvider provider;

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(provider);
    }

    @Override
    public void configure(final WebSecurity webSecurity) {
        webSecurity.ignoring().antMatchers("/login/**");
        // TODO Why can't I remove this
        webSecurity.ignoring().antMatchers("/logout/**");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .exceptionHandling()
                .and()
                .authenticationProvider(provider)
                .addFilterBefore(authenticationFilter(), AnonymousAuthenticationFilter.class)
                .authorizeRequests()
                .requestMatchers(PROTECTED_URLS)
                .authenticated()
                .and()
                .formLogin().disable()
                .httpBasic().disable()
                .logout().disable();
    }

    @Bean
    AuthenticationFilter authenticationFilter() throws Exception {
        final AuthenticationFilter filter = new AuthenticationFilter(PROTECTED_URLS);
        filter.setAuthenticationManager(authenticationManager());
        return filter;
    }

    @Bean
    AuthenticationEntryPoint forbiddenEntryPoint() {
        return new HttpStatusEntryPoint(HttpStatus.FORBIDDEN);
    }
}

CodePudding user response:

You can configure it in the method configure(HttpSecurity http) by simply adding

http.authorizeRequests().antMatchers("/login").permitAll();
http.authorizeRequests().antMatchers("/logout").permitAll();

CodePudding user response:

So I found how to make it work, there seems to have been two/three issues :

  • I had removed .csrf().disable() because it didn't seem to be good practice but actually this was causing some issues
  • order of the statements in the configure(HttpSecurity http) function is important, putting the logout() at the very end was apparently problematic
  • removed some uneeded code, which might or might have not contributed to the issue.

In the end here is my working SecurityConfiguration:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@AllArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
            new AntPathRequestMatcher("/api/**"),
            new AntPathRequestMatcher("/logout/**")
    );

    AuthenticationProvider provider;

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(provider);
    }

    @Override
    public void configure(final WebSecurity webSecurity) {
        webSecurity.ignoring().antMatchers("/login/**");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf().disable()
                .logout().disable()
                .exceptionHandling()
                .and()
                .authenticationProvider(provider)
                .addFilterBefore(authenticationFilter(), AnonymousAuthenticationFilter.class)
                .authorizeRequests()
                .requestMatchers(PROTECTED_URLS)
                .authenticated()
                .and();
    }

    @Bean
    AuthenticationFilter authenticationFilter() throws Exception {
        final AuthenticationFilter filter = new AuthenticationFilter(PROTECTED_URLS);
        filter.setAuthenticationManager(authenticationManager());
        return filter;
    }
}
  • Related