java - @AuthenticationPrincipal 与 Spring Boot 不工作

标签 java spring spring-security spring-boot

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

这是我的 Controller :

@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接口(interface):

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

然后在我的 UserDetailsS​​ervice 中:

@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)不起作用。我得到一个异常(exception):

"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

关于java - @AuthenticationPrincipal 与 Spring Boot 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35156390/

相关文章:

java - wildfly 8.2 读取耳内属性文件

java - 如何以编程方式在 Java 中创建 BDE 别名?

java - Spring Boot 有界自动配置

spring-security - 如何自定义 OAuth2 token 请求的授权 header

grails - 带Grails的Spring Security Core插件

spring - Grails Spring安全性插件-自定义登录和注销URL, Controller 和GSP

java - 在java中存储 map 哪个内存效率最高?

java - 如何使用内存来提高该算法的运行时间?

java - 我无法在jsp页面中包含css文件

java - Spring Batch 和 Spring 集成