14

I'm setting up my Spring Security (v4.0.1) web application. I want to have two authentication providers, an "in-memory" one to manage the administrator account and a custom one which refers to my own implementation. The system should attempt the authentication against the "in-memory" provider first of all and against the custom one in second place. My code looks like this:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, 
    AuthenticationProvider provider) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("admin")
            .password("s3cr3t")
            .authorities("ADMIN");
    auth.authenticationProvider(provider);
}

However, this code leads the framework to try my custom implementation first. It makes a bit of sense, since the AuthenticationManagerBuilder#authenticationProvider method adds a Provider to the internal List while the AuthenticationManagerBuilder#inMemoryAuthentication one configures it internally. How could I manage to get it work?

Aritz
  • 29,795
  • 13
  • 135
  • 209

2 Answers2

25

You can create your InMemoryUserDetailsManagerConfigurer manually and tell it to configure itself on the AuthenticationManagerBuilder when you have finished configuring it so it installs it's AuthenticationProvider before your custom one:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth,
        AuthenticationProvider provider) throws Exception {

    inMemoryConfigurer()
        .withUser("admin")
            .password("s3cr3t")
            .authorities("ADMIN")
        .and()
        .configure(auth);
    auth.authenticationProvider(provider);
}

private InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>
        inMemoryConfigurer() {
    return new InMemoryUserDetailsManagerConfigurer<>();
}

Normally what happens is that the InMemoryUserDetailsManagerConfigurer is created and added to the list of configurers that should be applied when the AuthenticationManager is built - which is after you've installed your custom AuthenticationProvider.

Raniz
  • 10,449
  • 1
  • 33
  • 61
3

More or less from spring.io Documentation

If you are using XML configuration (e.g. spring-security.xml):

<security:authentication-manager>
    <security:authentication-provider ref="FirstProvider" />
    <security:authentication-provider ref="SecondProvider" />
</security:authentication-manager>

(I am using that setup for one of Spring's built-in authentication provider next to a custom one, works fine)

If you are using Java Config, I can only reference some other person's post maclema on Java config for multiple authentication provider, since I have never (successfully) tried code config

Community
  • 1
  • 1
user2039709
  • 760
  • 7
  • 17
  • Thanks for the answer, I'm not using the XML configuration. What I want to achieve is something similar to your linked answer, but instead of having two custom authentication providers, I've got a custom one and other in-memory one, which is provided by Spring. As the in-memory one is defined over the AuthenticationManagerBuilder, I don't know how to add it. – Aritz Jun 19 '15 at 09:58