Spring Boot with custom UserDetailsService
java, spring, spring-boot, spring-data, spring-security
Solution
Your app seems to work for me (once I added `@Configuration` to the `AuthenticationSecurity`). Here's another working sample of a simple app with JPA `UserDetailsService` in case it helps: https://github.com/scratches/jpa-method-security-sample
Problem
What is the correct way to add my custom implementation of UserDetailsService (which uses Spring Data JPA) to Spring Boot app? ``` public class DatabaseUserDetailsService implements UserDetailsService { @Inject private UserAccountService userAccountService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userAccountService.getUserByEmail(username); return new MyUserDetails(user); } } public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> { public User findByEmail(String email); } @Service public class UserAccountService { @Inject protected UserRepository userRepository; public User getUserByEmail(String email) { return userRepository.findByEmail(email); } } @Configuration @ComponentScan @EnableAutoConfiguration @EnableGlobalMethodSecurity(prePostEnabled = true) @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.sample") @EntityScan(basePackages = { "com.sample" }) @EnableJpaAuditing(auditorAwareRef = "auditorProvider") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } ... @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } } @Order(Ordered.HIGHEST_PRECEDENCE + 10) protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter { @Inject private UserAccountService userAccountService; @Override public void init(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()); } @Bean public UserDetailsService userDetailsService() { return new DatabaseUserDetailsService(); } } } @Entity public class User extends AbstractPersistable<Long> { @ManyToMany private List<Role> roles = new ArrayList<Role>(); // getter, setter } @Entity public class Role extends AbstractPersistable<Long> { @Column(nullable = false) private String authority; // getter, setter } ``` I cannot start app beacouse I get (full exception here http://pastebin.com/gM804mvQ) ``` Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.sample.model.User.roles[com.sample.model.Role] at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1134) ``` When I configure my `ApplicationSecurity` with `auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery("...).authoritiesByUsernameQuery("...")` everything is working including JPA and Spring Data repositories.