我一直在关注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());
}
我期待的是实际的用户名,而不是...但是它目前正在返回 - 即用户的电子邮件地址。
最佳答案
我通过将最后几行更改为“解决”了该问题:
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 模型不会返回用户名作为主体名称,可能还需要对我的 User 对象执行更多工作,以将用户名字符串显式标记为主要名称。
如果有人对任何进一步的更新感兴趣,或者可以为在此问题上遇到不确定性的其他人提供更多信息,请发表评论或提供另一个(可能更好)答案。
关于java - Spring Boot 不使用 CustomAuthenticationProvider 返回用户名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56304926/