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?
The Authentication Manager is only a interface and actual implementation of the authenticate method is provided by the ProviderManager. The ProviderManager has a list of AuthenticationProviders. From it's authenticate method it calls the authenticate method of the appropriate AuthenticateProvider.
You need to declare SecurityFilterChain and WebSecurityCustomizer beans instead of overriding methods of WebSecurityConfigurerAdapter class.
inMemoryAuthentication() is the method of AuthenticationManagerBuilder class is used to perform in-memory authentication in the Spring Security. This method is used for creating the user with respective roles and passwords.
For a quick demonstration, we'll configure two authentication providers – a custom authentication provider and an in-memory authentication provider.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With