我一直遵循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());
}
我期望的是实际的用户名,而不是...当前正在返回的用户名-即用户的电子邮件地址。
答案 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显式标记为主体名称。
如果任何人对任何进一步的更新感兴趣,或者可以为遇到此问题的其他人提供更多信息,请发表评论或提供另一个(可能更好)的答案。