I am building a REST API using Spring and am currently authenticating all my requests using a custom user details service and this configuration code:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
I am also setting up a DaoAuthenticationProvider
to use the my user details service and using that to configure global security.
Now, I want to provide an endpoint that (while still secured with HTTP basic authentication) uses a different user details service to check whether the user is allowed to access the given resource.
How do I use two different user details services for different endpoints?
One thing you can do is have two WebSecurityConfigurerAdapter
s:
@EnableWebSecurity
@Order(Ordered.HIGHEST_PRECEDENCE)
class FirstEndpointConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
http
.requestMatchers()
.antMatchers("/specialendpoint")
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.userDetailsService(/* first of your userDetailsServices */);
}
}
@Configuration
class SecondEndpointConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
http // all other requests handled here
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.userDetailsService(/* second of your userDetailsServices */);
}
}
requestMatchers()
exists for targeting springSecurityFilterChain
s to specific endpoints.
EDIT: Mahmoud Odeh makes a good point that if the user bases are the same, then you may not need multiple UserDetailsService
instances. Instead, you can use one change that isolates your special endpoint by an authority on the user's account:
http
.authorizeRequests()
.antMatchers("/specialendpoint").hasAuthority("SPECIAL")
.anyRequest().authenticated()
.and()
.httpBasic();
Then, your single UserDetailsService
would look up all users. It would include the SPECIAL
GrantedAuthority
in the UserDetails
instance for users who have access to /specialendpoint
.