【发布时间】:2014-09-03 13:58:53
【问题描述】:
将我的 UserDetailsService(使用 Spring Data JPA)的自定义实现添加到 Spring Boot 应用程序的正确方法是什么?
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
}
我无法启动应用程序,因为我得到了(这里是完全例外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)
当我用auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery("...).authoritiesByUsernameQuery("...") 配置我的ApplicationSecurity 时,一切正常,包括JPA 和Spring Data 存储库。
【问题讨论】:
-
问题在于 JPA 映射。请添加用户和角色实体(类)。
-
已添加实体。无论如何,我认为实体没有问题,因为没有我的 UserDetailsService,JPA 可以正常工作。
-
不过我认为 Evgeni 是对的。该错误是映射错误。也许你可以分享一个完整的项目?
-
@DaveSyer,我在这里尝试将其最小化github.com/igo/spring-boot-userdetails。仍然无法运行,但是我遇到了另一个异常 NPE - DatabaseUserDetailsService 中的 UserAccountService 为空。请尝试,您可能知道如何使用自定义 UserDetailsService :)
-
您的应用似乎对我有用(一旦我将 @Configuration 添加到 AuthenticationSecurity)。我该如何打破它?
标签: java spring spring-security spring-data spring-boot