Zveratko
Zveratko

Reputation: 2811

Spring Boot security - multiple authentication providers

My problem is that I would like to have two Authentication providers

BEFORE: I have my UserDetailServiceImpl and I validated the users against DB(not sure what provider is it) The user got role according to the data in DB

NOW: I have used ActiveDirectoryLdapAuthentication provider as follows

  @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
        auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider()).userDetailsService(userDetailService);
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
    }
    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
       MyActiveDirectoryLdapAuthenticationProvider provider = new MyActiveDirectoryLdapAuthenticationProvider(domain, url, rootDN);
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);

        return provider;
    }

I made it work, so I'm able to authenticate.

THE PROBLEM:

  1. I'm unable now to login with the database users anymore, only LDAP now.
  2. The UserDetailsService is not used, so which role the user has?
  3. Is there way how to add some default role to LDAP authenticated user?

So how to enable both providers? How to add roles to user, authenticated through LDAP auth.provider?

I would also really appreciate "big picture" description of what is going on here(under the hood). What is the role of each of the classes used here, it is really unclear how does it work(AuthenticationManager, AuthenticationManagerBuilder, AuthenticationProvider etc.) Maybe it is just hidden by autoconfiguration and so, but even looking to Spring Security directly does not make me any wiser.

Thanks for any hints

UPDATE This code seems to be working properly

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

    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        MyActiveDirectoryLdapAuthenticationProvider provider = new MyActiveDirectoryLdapAuthenticationProvider(domain, url, rootDN);
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        provider.setAuthoritiesMapper(new SimpleAuthorityMapper());
        return provider;
    }

Upvotes: 4

Views: 6758

Answers (1)

Dave Syer
Dave Syer

Reputation: 58094

Too many questions!

Both providers are enabled since you add them both to the AuthenticationManagerBuilder. But you add them both to the same filter chain and both accept the same kind of Authentication as inputs, so one of them always masks the other.

The standard LdapAuthenticationProvider has an authoritiesMapper that you can use to map authorities from the directory entries to your users (normally it is done out of the box using directory groups, e.g. see sample). I suppose if your directory doesn't contain groups you could make all users have the same authorities or something with a custom mapper.

Your @Beans of type AuthenticationManager and AuthenticationProvider look suspiciously redundant (and possibly harmful since they are global, and you are configuring the AuthenticationManagerBuilder for a single filter chain). I doubt you need that AuthenticationManager method at all and the other one doesn't need to be public or a @Bean (probably).

Upvotes: 1

Related Questions