I'm trying to define my own UserDetailsService for api calls.
So here is my security conf :
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration {
@Bean
@Order(1)
public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http, @Qualifier("apiUserDetailsService") ApiUserDetailsService apiUserDetailsService) throws Exception {
http.antMatcher("/api/**")
.userDetailsService(apiUserDetailsService)
.csrf().disable()
.cors(Customizer.withDefaults())
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(new AuthenticationFallbackEntryPoint()))
.sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults());
return http.build();
}
I expect the "ApiUserDetailsService" bean to be scanned and constructor-injected in my apiSecurityFilterChain.
Here is my ApiSecurityFilterChain (this is the "test" version) :
@Component
@Primary
@Qualifier("apiUserDetailsService")
public class ApiUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String nni) {
// (...)
return new ApiUserDetails(apiUserDto, authorities);
}
}
Here is how I declare my AuthentTest (which worked fine before the introduction of this custom UserDetailsService) :
@WebMvcTest({ UserController.class })
@Import({ SecurityConfiguration.class, GrantedPortalRoleConverter.class, ApiUserDetailsService.class })
@TestInstance(Lifecycle.PER_CLASS)
class AuthenticationTest {
Here is the bad result I get when my test starts :
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'apiSecurityFilterChain' defined in class path resource [fr/mycomp/dvs/configuration/SecurityConfiguration.class]: Unsatisfied dependency expressed through method 'apiSecurityFilterChain' parameter 1;
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'fr.mycomp.dvs.security.ApiUserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value="apiUserDetailsService")}
Which mistake am I doing which prevents ApiUserDetailsService bean instanciation or detection as candidate ?
UPDATE : I have to stay my webapp starts with no warning or error, only the JUnit test causes problems.
UPDATE 2 : I've changed to ApiUserDetailsService (my actual implementation) to UserDetailsService and first the message was exactly the same, like if SecurityConfiguration was never rebuilt, then it worked. I think I had multiple layers of problems preventing it to work.