@AuthenticationPrincipal与Spring Boot无法正常工作

使用Spring Boot 1.3.1,我遇到了@AuthenticationPrincipal问题。

这是我的控制器:

 @RestController @RequestMapping("/api/user") public class UserController { @RequestMapping("/") public UserDto user(@AuthenticationPrincipal(errorOnInvalidType = true) User user) { return UserDto.fromUser(user); } } 

这是我自定义的User类:

 @Entity() @Table(name = "app_user") public class User extends AbstractEntity implements Serializable { // ------------------------------ FIELDS ------------------------------ @NotNull @Column(unique = true) @Pattern(regexp = "[a-zA-Z_\\-\\.0-9]+") @Size(min = 1, max = 20) private String username; private String password; @Column(unique = true) @Email private String emailAddress; @Enumerated(EnumType.STRING) @NotNull private UserRole role; } 

我还创建了一个类来确认Spring Security的UserDetails接口:

 public class CustomUserDetails extends User implements UserDetails { public CustomUserDetails(User user) { super(user); } @Override public Collection getAuthorities() { return Sets.newHashSet(new SimpleGrantedAuthority("ROLE_" + getRole().name())); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } } 

然后在我的UserDetailsService

 @Override public CustomUserDetails loadUserByUsername(String username) throws UsernameNotFoundException { com.company.app.domain.account.User user = userRepository.findByUsername(username); if (user != null) { return new CustomUserDetails(user); } else { throw new UsernameNotFoundException(format("User %s does not exist!", username)); } } 

我有一个完美的集成测试。 但是,运行应用程序本身(来自IntelliJ IDEA)不起作用。 我得到一个例外:

 "CustomUserDetails{id=UserId{id=401868de-99ff-4bae-bcb6-225e3062ed33}} is not assignable to class com.company.app.domain.account.User" 

但事实并非如此,因为CustomUserDetails是我的自定义User类的子类。

检查调试器,我看到AuthenticationPrincipalArgumentResolver中的此代码失败:

 if (principal != null && !parameter.getParameterType().isAssignableFrom(principal.getClass())) { 

parameter.getParameterType()的类加载器是RestartClassloader的实例,而principal.getClass()有一个类加载器,它是Launcher$AppClassLoader一个实例。

这是Spring Boot或Spring Security中的错误还是我做错了什么?

更新:

我可以确认禁用Spring Boot的devtools使其工作:

 public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(MyApplication.class, args); } 

为了帮助遇到同样问题的其他人,这是Spring Boot DevTools和Spring Security OAuth的限制。 它正在本期跟踪: https : //github.com/spring-projects/spring-boot/issues/5071