2016-02-02 5 views
1

Использование Spring Boot 1.3.1, у меня проблемы с @AuthenticationPrincipal.@AuthenticationPrincipal с пружиной Boot не работает

Это мой контроллер:

@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; 
} 

Я также создал класс для подтверждения интерфейса UserDetails в Spring Security:

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:

@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, или я что-то не так?

UPDATE:

Я могу подтвердить, что отключение DevTools весны Ботинок делает его работу:

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

ответ

0

Чтобы помочь кому-то, кто попадет в ту же проблему, что это ограничение в Spring загрузочного Devtools и Spring Security OAuth. Он отслеживается в этом выпуске: https://github.com/spring-projects/spring-boot/issues/5071

+0

В качестве обходного пути используйте 'InMemoryTokenStore' вместо' JDBCTokenStore' –

Смежные вопросы