Я следил за Учебное пособие по весенней двухфакторной аутентификации Baeldung для реализации 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%, почему моя относительно простая модель пользователя не возвращает имя пользователя в качестве основного имени, возможно, есть еще какая-то работа, которую следует выполнить для моего объекта пользователя, чтобы явно пометить строку имени пользователя как основное имя .
Если кто-то заинтересован в каких-либо дальнейших обновлениях или может предоставить дополнительную информацию для тех, кто испытывает неуверенность в этом вопросе, оставьте комментарий или дайте другой (вероятно, лучший) ответ.