I have found several questions about similar problems but none of them is exactly my case.
I am using the following class to configure the authentication/authorization in my application (a REST API).
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class); @Override public void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .csrf().disable() .authorizeRequests() .and() .exceptionHandling(e -> e .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)) ) .antMatcher("/application-api/v1/**").authorizeRequests() .antMatchers("/application-api/v1/non-protected").permitAll() .anyRequest() .authenticated() .and() .oauth2ResourceServer() .opaqueToken(); } @Override protected UserDetailsService userDetailsService() { return new ApplicationUserDetailsService(); } }
No matter what I try, my custom ApplicationUserDetailsService is never used. Can anyone see what is wrong with this configuration?
I have also tried to specify the following bean:
@Service public class ApplicationUserDetailsService implements UserDetailsService { private static final Logger logger = LoggerFactory.getLogger(ApplicationUserDetailsService.class); public ApplicationUserDetailsService() { logger.debug("Creating instance of ApplicationUserDetailsService"); } @Override public UserDetails loadUserByUsername(String userName) { logger.debug("Creating user details for {}", userName); return new ApplicationUser(userName); } }
It did not work either.
########### UPDATE ###########
I have modified my SecurityConfiguration as follows:
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class); @Qualifier("applicationUserDetailsService") @Autowired private UserDetailsService userDetailsService; @Override public void configure(HttpSecurity httpSecurity) throws Exception { logger.info("Oauth2 enabled: {}", enabled); httpSecurity.sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .csrf().disable() .exceptionHandling(e -> e .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)) ) .antMatcher("/application-api/v1/**").authorizeRequests() .antMatchers("/", "/application-api/unprotected").permitAll() .anyRequest() .authenticated() .and() .oauth2ResourceServer() .opaqueToken(); } @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder()); } @Bean(name="passwordEncoder") public PasswordEncoder passwordencoder(){ return new BCryptPasswordEncoder(); } @Override protected UserDetailsService userDetailsService() { return userDetailsService; } }
I can see that my instance is used in the configuration, but nevertheless it is never called.
Advertisement
Answer
The problem is not with the injection of the bean. Given that you are seeing the expected bean injected, the reason is probably that the service is not used.
You need to check what authentication provider you are using. With the default providers, the service is used only if you your authentication provider is based on username and password.
See for example the Spring documentation:
The following article describes how to customise the user details.