Spring Security @AuthenticationPrincipal

Luk*_*hey 13 java spring spring-security

我一直在努力让@AuthenticationPrincipal与自定义User类一起正常工作.不幸的是,用户始终为空.这是代码:

调节器

@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index(@AuthenticationPrincipal User user) {
    ModelAndView mav= new ModelAndView("/web/index");
    mav.addObject("user", user);
    return mav;
}
Run Code Online (Sandbox Code Playgroud)

安全配置

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    CustomUserDetailsService customUserDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
    }
Run Code Online (Sandbox Code Playgroud)

}

CustomUserDetailsS​​ervice

@Component
public class CustomUserDetailsService implements UserDetailsService {

@Autowired
UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    // Spring Data findByXY function
    return userRepository.findByUsername(username);
}
Run Code Online (Sandbox Code Playgroud)

用户实体

public class User implements UserDetails{
    private String username;
    private String password;
    private Collection<Authority> authorities;

    // Getters and Setters

}
Run Code Online (Sandbox Code Playgroud)

权威实体

public class Authority implements GrantedAuthority{
    private User user;
    private String role;

    // Getters and Setters

    @Override
    public String getAuthority() {
        return this.getRole();
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过在网上找到的各种解决方案,例如转换我的自定义用户对象:

return new org.springframework.security.core.userdetails.User(user.getLogin(), user.getPassword(), true, true, true, true,  authorities);
Run Code Online (Sandbox Code Playgroud)

获取活动用户的其他方法没有问题,但我发现@AuthenticationProvider CustomUserObject是最干净的方式,这就是为什么我想让它工作.任何帮助是极大的赞赏.

use*_*039 7

在我的情况下,我得到一个String返回(用户名)而不是UserDetails对象,即你应该将方法签名定义为

public ModelAndView index(@AuthenticationPrincipal String username)
Run Code Online (Sandbox Code Playgroud)

这并不奇怪,因为@AuthenticationPrincipal实际上返回Authentication.getPrincipal()并根据文档:

在带有用户名和密码的身份验证请求的情况下,这将是用户名。调用者应为身份验证请求填充主体。

AuthenticationManager 实现通常会返回一个包含更丰富信息的身份验证作为应用程序使用的主体。许多身份验证提供程序将创建一个 UserDetails 对象作为主体。请参阅:https : //docs.spring.io/spring-security/site/docs/5.0.0.RELEASE/api/

所以,我假设你的AuthenticationManager实现只返回一个用户名


小智 5

无需使用@AuthenticationPrincipal,您可以在方法参数中直接为已认证用户指定依赖项。如下所示

@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index(Principal user) {
    ModelAndView mav= new ModelAndView("/web/index");
    mav.addObject("user", user);
    return mav;
} 
Run Code Online (Sandbox Code Playgroud)

这个Principal对象将是通过spring安全性认证的实际对象。当方法被调用时,Spring会为您注入这个。

  • 正如我所说,这些方法都可以正常工作。但是根据文档,只要我的用户对象实现UserDetails并且启用WebMvcSecurity(我正在使用Spring Security 4.0.2),我就应该能够通过AuthenticationPrincipal批注获取我的自定义用户对象。知道我可能会缺少什么吗? (3认同)
  • @RémiDoolaeghe - 这是一个迟到的答案,但您需要获得一个 `UserDetails` 的实例,而不仅仅是 `User`。 (2认同)