Warm tip: This article is reproduced from serverfault.com, please click

ActiveDirectoryLdapAuthenticationProvider and authentication using userDetailsService

发布于 2020-12-01 00:30:39

I have two different users in my application. Ldap users and api users. Ldap users have privilege to access an endpoint and api users a different endpoint. I have implemented the api user authentication using UserDetailsService and having the details in my application.yaml file. The issue I am facing now is, The endpoint that only Ldap users should access is now being accessed my api users as well. How can I prevent this. Please find my code snippet below

public class ServiceSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("ldapProvider")
    private AuthenticationProvider authenticationProvider;

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

// security for apiuser
              http
                .authorizeRequests()
                .antMatchers(“/abcd/**).hasRole(“admin”)
                .and()
                .httpBasic().and().userDetailsService(userDetailsService());
      

// security for ldap users
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers(“/ghhgh” + "/**").fullyAuthenticated()
                .antMatchers("/login*").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().and()
                .authenticationProvider(authenticationProvider)
                .exceptionHandling();
    }

    public UserDetailsService userDetailsService() {

        UserDetails user = User.withUsername(“api”)
                .password(passwordEncoder().encode(“test”))
                .roles(“admin”)
              return new InMemoryUserDetailsManager(user);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
Questioner
SJB
Viewed
11
Amir Schnell 2020-12-03 18:38:04

In spring security it is indeed possible to register multiple authentication mechanisms.

BUT you cannot register a specific authentication provider to a specific route.
The spring securty docs say:

ProviderManager is the most commonly used implementation of AuthenticationManager. ProviderManager delegates to a List of AuthenticationProviders. Each AuthenticationProvider has an opportunity to indicate that authentication should be successful, fail, or indicate it cannot make a decision and allow a downstream AuthenticationProvider to decide.

So in every request, the registered AuthenticationProviders are checked one after the other until one is successful, or all fail.

To solve your problem, you need to define multiple custom authorities, that you assign your users.
Then you secure your endpoints using these authorities.

E.g. you give every ldap user the authority LDAP_USER and every api user the authority API_USER. Then you configure your security accordingly:

Register all AuthenticationProviders:


@Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.authenticationProvider(ldapProvider);
        auth.userDetailsService(userDetailsService());
    }

And configure the endpoints:


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


    http
      (...)
      .authorizeRequests()

// security for apiuser
      .antMatchers(“/abcd/**).hasRole(“API_USER”)

// security for ldap users
      .antMatchers(“/ghhgh” + "/**").hasRole("LDAP_USER")
      (...)
    }