使用Spring Boot 1.3.1,我在遇到问题@AuthenticationPrincipal。
@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<UserId> 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; }
我还创建了一个类来确认UserDetailsSpring Security 的接口:
UserDetails
public class CustomUserDetails extends User implements UserDetails { public CustomUserDetails(User user) { super(user); } @Override public Collection<? extends GrantedAuthority> 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:
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类的子类。
CustomUserDetails
User
通过调试器检查,我发现此代码AuthenticationPrincipalArgumentResolver失败:
AuthenticationPrincipalArgumentResolver
if (principal != null && !parameter.getParameterType().isAssignableFrom(principal.getClass())) {
的类加载器parameter.getParameterType()是的实例RestartClassloader,而principal.getClass()具有的类加载器是的实例Launcher$AppClassLoader。
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