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();
}
}
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 ofAuthenticationManager
.ProviderManager
delegates to aList
ofAuthenticationProviders
. EachAuthenticationProvider
has an opportunity to indicate that authentication should be successful, fail, or indicate it cannot make a decision and allow a downstreamAuthenticationProvider
to decide.
So in every request, the registered AuthenticationProvider
s 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")
(...)
}
Hi @Amir Schenell, thanks for you explanation. I tried the same but I am still able to access the ldap endpoints with apiuser
can you post your current config into your question, so I can have a lokk at it?
Hi @Amir Schnell , I missed adding authority to ldap and that fixed it. Thankyou so much