春季安防@AuthenticationPrincipal

2022-09-01 23:30:43

我一直在努力@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;
}

安全配置

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    CustomUserDetailsService customUserDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
    }

}

自定义用户详细信息服务

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

用户实体

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

    // Getters and Setters

}

权限实体

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

    // Getters and Setters

    @Override
    public String getAuthority() {
        return this.getRole();
    }
}

我已经尝试了在线找到的各种解决方案,例如,像这样转换我的自定义用户对象:

return new org.springframework.security.core.userdetails.User(user.getLogin(), user.getPassword(), true, true, true, true,  authorities);

获取活动用户的其他方法可以正常工作,但我发现@AuthenticationProvider CustomUserObject是最干净的方式,这就是为什么我想让它工作的原因。任何帮助都非常感谢。


答案 1

您可以使用@AuthenticationPrincipal而不是直接在方法参数中指定经过身份验证的用户的依赖项。如下所述

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

此主体对象将通过 spring 安全性进行身份验证的实际对象。当调用该方法时,Spring将为您注入此内容。


答案 2

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

public ModelAndView index(@AuthenticationPrincipal String username)

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

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

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

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


推荐