Spring Boot不使用CustomAuthenticationProvider返回用户名

时间:2019-05-25 12:43:58

标签: java spring-boot spring-security

我一直遵循Baeldung的Spring 2FA tutorial来实施2FA。我已经按照说明创建了CustomAuthenticationProvider,但是它的行为不符合预期。

奇怪的是,登录后,使用Principal.getName()时会显示我不熟悉的用户名格式:

com.appname.models.User@69080b62

由于应用程序的某些部分依赖于此来获取详细信息,因此这是不合适的,但我一直在努力了解哪里出了问题。我进行了一些研究,但没有正确的名称和格式名称,我一直在努力寻找合适的结果。

    public Authentication authenticate(Authentication auth) throws AuthenticationException {

        User user = userRepository.findByUsername(auth.getName());

        if(user == null) {

            throw new BadCredentialsException("Invalid username or password");

        }

        if(user.getTwoFactor()) {

            //as per tutorial

        }
        //this returns the "correct" username
        System.out.println(user.getUsername());

        final Authentication result = super.authenticate(auth);
        //I suspect it's here that the issue is occurring, though any pointers in the right direction would be appreciated
        return new UsernamePasswordAuthenticationToken(user, result.getCredentials(), result.getAuthorities());

}

我期望的是实际的用户名,而不是...当前正在返回的用户名-即用户的电子邮件地址。

1 个答案:

答案 0 :(得分:2)

我通过将最后几行更改为“解决了”问题:

final Authentication result = super.authenticate(auth);

UserDetails userDetails = userDetailsService.loadUserByUsername(auth.getName());

return new UsernamePasswordAuthenticationToken(userDetails, 
        result.getCredentials(), userDetails.getAuthorities());

......,其中userDetailsService指向Spring Security UserDetailsService的简单实现,该实现返回Spring Security UserDetails对象,如下所示:

@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) {

    User user = userRepository.findByUsername(username);

    if(user == null) throw new UsernameNotFoundException(username);

    Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
    for (Role role : user.getRoles()) {

        grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));

    }

    return new org.springframework.security.core.userdetails.User(user.getUsername(), 
            user.getPassword(), user.getEnabled(), user.getNonExpired(), 
            user.getCredentialsNonExpired(), user.getNonLocked(), grantedAuthorities);

}

这在我的应用程序中的其他地方都有效,因此我认为它在这里也可能适用。我相信我可以将最后一个论点保留为result.getAuthorities()。我想我也可以重构,因此我不会两次访问数据库,但是现在我很高兴它能起作用。

我不确定100%为什么相对简单的用户模型不会将用户名作为主体名称返回,可能是我的User对象需要做更多的工作以将用户名String显式标记为主体名称。

如果任何人对任何进一步的更新感兴趣,或者可以为遇到此问题的其他人提供更多信息,请发表评论或提供另一个(可能更好)的答案。