Search code examples
springspring-securityspring-java-config

Spring Security, Why second WebSecurityConfigurerAdapter is not working?


Update:

Adding .antMatcher("/admin/**") in the first WebSecurityConfigurerAdapter makes it work now, why is that?

now configure method of first WebSecurityConfigurerAdapter is:

        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher("/admin/**")                 // <<<<<<<<<<<<<<--- newly added
                    .authorizeRequests()
                    .antMatchers("/admin/**").hasRole("ADM")
                    .and()
                .formLogin()
                    .loginPage("/admin/login")
                    .permitAll()
                .logout()
                    .permitAll();
        }

My site divides into 2 parts, one for user and another for manager, so I configured two WebSecurityConfigurerAdapters in my web app for each of them.

like this:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig  {

    @Configuration
    @Order(1)
    public static class ManagerSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Autowired
        private ManagerDetailsService managerDetailsService;

        //allow access to static resouces
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/pc/css/**", "/pc/js/**", "/pc/img/**");
            web.ignoring().antMatchers("/mobile/css/**", "/mobile/js/**", "/mobile/img/**");
        }

        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/admin/**").hasRole("ADM")
                    .and()
                .formLogin()
                    .loginPage("/admin/login")
                    .permitAll()
                .logout()
                    .permitAll();
        }

        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .userDetailsService(managerDetailsService);
        }
    }

    @Configuration
    @Order(2)
    public static class UserLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Autowired
        private WeUserDetailsService weUserDetailsService;

        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http
                .authorizeRequests()
                    .antMatchers("/user/**").hasRole("USER")
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/user/login")
                    .permitAll()
                .logout()
                    .permitAll();

            http.addFilterBefore(new WeAuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(weUserDetailsService);
        }
    }
}

The problem is that the second WebSecurityConfigurerAdapter is not working, if I enter: /admin into browser, it will take me to the /admin/login as expected,

while if I enter /user, it will directly go the action in controller, by passed the security filter.

why is that?


Solution

  • The reason is first WebSecurityConfigurerAdapter's

            http
                .authorizeRequests()
    

    This will match all the urls, makes the second UserLoginWebSecurityConfigurerAdapter useless, adding antMatcher can help limit the urls it can match, that's why adding .antMatcher("/admin/**") can work.