Spring Boot не возвращает имя пользователя с помощью CustomAuthenticationProvider - PullRequest
2 голосов
/ 25 мая 2019

Я следовал учебному пособию Baeldung Spring 2FA , чтобы реализовать 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 Ответ

2 голосов
/ 25 мая 2019

Я «решил» проблему, изменив последние несколько строк на:

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 как основное имя.

Если кто-то заинтересован в каких-либо дальнейших обновлениях или может предоставить дополнительную информацию для тех, кто испытывает неуверенность в этом вопросе, оставьте комментарий или предоставьте другой (вероятно, лучший) ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...