복붙노트

[SPRING] 스프링 부트가 작동하지 않는 @AuthenticationPrincipal

SPRING

스프링 부트가 작동하지 않는 @AuthenticationPrincipal

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

이것은 내 사용자 정의 사용자 클래스입니다.

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

또한 Spring 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 :

@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는 내 사용자 정의 사용자 클래스의 서브 클래스이기 때문에 이것은 사실이 아닙니다.

디버거로 확인하면 AuthenticationPrincipalArgumentResolver의 다음 코드가 실패합니다.

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

parameter.getParameterType ()의 클래스 로더는 RestartClassloader의 인스턴스이고 principal.getClass ()에는 Launcher $ AppClassLoader의 인스턴스 인 클래스 로더가 있습니다.

이것은 Spring Boot 나 Spring Security의 버그입니까? 아니면 제가 잘못하고 있습니까?

최신 정보:

나는 스프링 부트의 devtools를 비활성화하면 제대로 작동하는지 확인할 수있다.

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

해결법

  1. ==============================

    1.같은 문제를 겪는 다른 사람들을 돕기 위해 이것은 Spring Boot DevTools와 Spring Security OAuth의 제한 사항입니다. 이 문제는 https://github.com/spring-projects/spring-boot/issues/5071에서 추적 중입니다.

    같은 문제를 겪는 다른 사람들을 돕기 위해 이것은 Spring Boot DevTools와 Spring Security OAuth의 제한 사항입니다. 이 문제는 https://github.com/spring-projects/spring-boot/issues/5071에서 추적 중입니다.

  2. from https://stackoverflow.com/questions/35156390/authenticationprincipal-with-spring-boot-not-working by cc-by-sa and MIT license