为什么Spring安全性基于用户名而不是用户ID?

时间:2018-01-15 18:41:49

标签: spring spring-boot spring-security spring-oauth2

在Spring安全性中,UserDetails使用username作为用户的标识符。我的用户模型有多种类型的标识,并有多种身份验证方式(通过电子邮件,电话号码,Facebook等)。

我正在使用AuthorizationServerEndpointsConfigurer来配置我的oauth2端点。 JdbcTokenStoreuser_name存储在数据库中,我需要存储的是userId。我已经更改JdbcTokenStore以满足我的需求,但我不明白为什么spring框架假设用户名是唯一标识符,我的应用甚至不使用用户名。

例如,TokenStore地址findTokensByClientIdAndUserName基于用户名,为什么不findTokensByClientIdAndUserId?如果我使用电子邮件或电话号码对用户进行身份验证,我该如何获得该用户的所有令牌?

为什么spring使用username来存储用户唯一标识,为什么不使用用户ID?

我的用户模型示例:idemailphone numberfacebook_idname。电子邮件,电话号码和Facebook ID是可选的,只需要其中一个。在这种情况下,用户名的最佳候选者是什么?我应该在春天使用用户ID作为用户名吗?

1 个答案:

答案 0 :(得分:3)

不确定我是否理解了整个问题,但会尝试为UserDetailService提供最佳解释。 UserDetailsS​​ervice的方法loadByUsername只是一种方法,它允许您从数据库中检索用户,并将其与来自客户端的请求中的凭据进行比较,以查看它是现有用户还是现有用户。虽然方法的名称是loadUserByUsername,但这并不意味着您必须逐字传递用户名,您可以传递任何参数,如电子邮件,电话号码或您认证所依据的任何内容。

以下是该服务的示例实现,其中我通过UserRepository调用数据库并将其作为参数电子邮件来识别我的用户。

@Service
public class CustomUserDetailsService implements UserDetailsService {

    private UserRepository userRepository;

    @Autowired
    public CustomUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Here I am retrieving the user from my database where the primary key is 
// email
        User user = userRepository.findByEmail(username);

        if(user == null) {
            throw new UsernameNotFoundException("Username not found!");
        }

        CustomUserDetails customUserDetails = new CustomUserDetails(user);
        return customUserDetails;
    }
}