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