Spring security antMatcher does not work

17,460

The pattern must not contain the context path, see AntPathRequestMatcher:

Matcher which compares a pre-defined ant-style pattern against the URL ( servletPath + pathInfo) of an HttpServletRequest.

and HttpServletRequest.html#getServletPath:

Returns the part of this request's URL that calls the servlet. This path starts with a "/" character and includes either the servlet name or a path to the servlet, but does not include any extra path information or a query string. Same as the value of the CGI variable SCRIPT_NAME.

and HttpServletRequest.html#getContextPath:

Returns the portion of the request URI that indicates the context of the request. The context path always comes first in a request URI. The path starts with a "/" character but does not end with a "/" character. For servlets in the default (root) context, this method returns "". The container does not decode this string.

Your modified and simplified code:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/test/**")
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin();
    }
Share:
17,460
tryingToLearn
Author by

tryingToLearn

Coder. Rookie blogger. Perpetually curious. Dreamer. Big fan of open source community. Loves programming and exploring new technical fields.

Updated on June 16, 2022

Comments

  • tryingToLearn
    tryingToLearn almost 2 years

    EDIT:

    I further drilled down the problem and turns out issue persists even with single configuration. If I use single configuration and keep

    http.antMatcher("/api/test/**")
    

    urls don't get secured. Removing the antMatcher and antMatchers immediately secures the url. i.e if I use:

    http.httpBasic()
        .and()
        .authorizeRequests()
        .anyRequest()
        .authenticated();
    

    then only spring security is securing url. Why isn't antMatcher functioning?

    (Updated the title to include actual issue.)


    Original Post:

    I have referred following stackoverflow questions:

    1. Spring REST security - Secure different URLs differently

    2. Using multiple WebSecurityConfigurerAdapter with different AuthenticationProviders (basic auth for API and LDAP for web app)

    and spring security doc:

    https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#multiple-httpsecurity

    But I am not able to configure multiple http security elements. When I follow the official spring doc, it works in my case only becuase of the fact that the second http security element is a catch-all, but as soon as I add a specific url, all the urls can be accessed without any authentication.

    Here's my code:

    @EnableWebSecurity
    @Configuration
    public class SecurityConfig {
    
        @Bean                                                             
        public UserDetailsService userDetailsService() throws Exception {
            InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
            manager.createUser(User.withUsername("user").password("userPass").roles("USER").build());
            manager.createUser(User.withUsername("admin").password("adminPass").roles("ADMIN").build());
            return manager;
        }
    
    
        @Configuration
        @Order(1)                                                        
        public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
    
            @Override       
            public void configure(AuthenticationManagerBuilder auth) 
              throws Exception {            
                auth.inMemoryAuthentication().withUser("user").password("user").roles("USER");
                auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
            }
    
            protected void configure(HttpSecurity http) throws Exception {
                http
                    .antMatcher("/api/v1/**")                               
                    .authorizeRequests()
                    .antMatchers("/api/v1/**").authenticated()
                        .and()
                    .httpBasic();
            }
        }
    
        @Configuration
        @Order(2)
        public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
    
            @Override       
            public void configure(AuthenticationManagerBuilder auth) 
              throws Exception {
    
                auth.inMemoryAuthentication().withUser("user1").password("user").roles("USER");
                auth.inMemoryAuthentication().withUser("admin1").password("admin").roles("ADMIN");
            }
    
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http
                    .antMatcher("/api/test/**")
                    .authorizeRequests()
                    .antMatchers("/api/test/**").authenticated()
                        .and()
                    .formLogin();
            }
        }
    }
    

    Now any url can be accessed. If I remove antMatcher from second configuration, all the urls become secured.