SecurityContextHolder.getContext (). GetAuthentication (). GetCredentials () возвращает нулевое значение после аутентификации. - PullRequest
0 голосов
/ 27 ноября 2018

Я создал простое приложение Spring Web MVC, и у меня есть одна проблема.После аутентификации я пытаюсь получить объект аутентификации, и по какой-то причине его учетные данные являются нулевыми.

enter image description here

В этом проекте у меня есть пользовательский AuthenticationProvider, который выглядит следующим образом:

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @PostConstruct
    public void init() {
        roleService.AddStandardRolesIfNeeded();
        userService.AddUserWithAdminRoleIfNotExists("a"); 
    }


    public Authentication authenticate(Authentication authentication) throws AuthenticationException {


        Object credentials = authentication.getCredentials();
        if(!(credentials instanceof String)) {
            return null;
        }

        String username = authentication.getName();
        String password = credentials.toString(); //password isn't null here


        User user = userService.findByUsernameAndPassword(username, password);


        if(user == null) {
            throw new BadCredentialsException("Authentication failed for " + username);
        }


        List<GrantedAuthority> authorities = new ArrayList<>();
        for(Role role : user.getRoles()) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }

        Authentication auth = new 
                UsernamePasswordAuthenticationToken(username, password, authorities);


        return auth;
    }

    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}

Мне интересно, если этопреднамеренно сделано весной безопасности или я что-то упускаю.

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Я решил эту проблему, передав объект-конструктор UsernamePasswordAuthenticationToken вместо имени пользователя вместо принципала.

Я изменил это:

Authentication auth = new 
                UsernamePasswordAuthenticationToken(username, password, authorities);

на следующее:

Authentication auth = new 
                    UsernamePasswordAuthenticationToken(user, password, authorities);

А в контроллере я получаю пользователя так:

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
0 голосов
/ 22 июля 2019

Поскольку учетные данные будут удалены после успешной аутентификации, необходимо добавить eraseCredentials(false) к AuthenticationManagerBuilder конфигурации.Как код ниже:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthProvider).eraseCredentials(false);
}

Уже поздно, но я думаю, что это правильный ответ в соответствии с вопросом.

0 голосов
/ 27 ноября 2018

Аутентификация должна быть сделана примерно так:

@Override
public Authentication authenticate(final Authentication authentication) {
    //better to use optionals with repositories, they greatly reduce NullPointer exception quantity
    final SomeUser user = UserRepository.findByUsernameIgnoreCase(authentication.getName())
                .orElseThrow(() -> new UsernameNotFoundException("some message"));
    try {
            final Authentication auth = super.authenticate(authentication);
            //can add logic here, such as login time recording
            return auth;
    } catch (...) {
           //handle various exceptions here, for example failed login attempts and user locking
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...