«1. Обзор

В этом кратком руководстве мы обсудим, как автоматически аутентифицировать пользователей сразу после процесса регистрации — в реализации Spring Security.

Проще говоря, как только пользователь завершает регистрацию, он обычно перенаправляется на страницу входа в систему и теперь должен повторно ввести свое имя пользователя и пароль.

Давайте посмотрим, как мы можем избежать этого с помощью автоматической аутентификации пользователя.

Прежде чем мы начнем, обратите внимание, что мы работаем в рамках регистрационной серии здесь, на сайте.

2. Использование HttpServletRequest

Очень простой способ программно принудительно выполнить аутентификацию — использовать метод login() HttpServletRequest:

public void authWithHttpServletRequest(HttpServletRequest request, String username, String password) {
    try {
        request.login(username, password);
    } catch (ServletException e) {
        LOGGER.error("Error while login ", e);
    }
}

Теперь, что под капотом, HttpServletRequest.login() API использует AuthenticationManager для выполнения аутентификации.

Также важно понимать и обрабатывать исключение ServletException, которое может возникнуть на этом уровне.

3. Использование AuthenticationManager

Далее мы также можем напрямую создать UsernamePasswordAuthenticationToken, а затем пройти через стандартный AuthenticationManager вручную:

public void authWithAuthManager(HttpServletRequest request, String username, String password) {
    UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password);
    authToken.setDetails(new WebAuthenticationDetails(request));
    
    Authentication authentication = authenticationManager.authenticate(authToken);
    
    SecurityContextHolder.getContext().setAuthentication(authentication);
}

Обратите внимание, как мы создаем запрос токена, передавая его через стандартный поток проверки подлинности, а затем явно задавая результат в текущем контексте безопасности.

4. Сложная регистрация

В некоторых, более сложных сценариях, процесс регистрации состоит из нескольких этапов, таких как, например, этап подтверждения до тех пор, пока пользователь не сможет войти в систему.

В таких случаях, конечно, важно понимать, где именно мы можем автоматически аутентифицировать пользователя. Мы не можем сделать это сразу после того, как они зарегистрируются, потому что в этот момент вновь созданная учетная запись все еще отключена.

Проще говоря — мы должны выполнить автоматическую аутентификацию после того, как они подтвердят свою учетную запись.

Кроме того, имейте в виду, что в этот момент у нас больше нет доступа к их фактическим необработанным учетным данным. У нас есть доступ только к закодированному паролю пользователя — и это то, что мы будем использовать здесь:

public void authWithoutPassword(User user){
    
    List<Privilege> privileges = user.getRoles().stream().map(Role::getPrivileges)
      .flatMap(Collection::stream).distinct().collect(Collectors.toList());
    List<GrantedAuthority> authorities = privileges.stream()
        .map(p -> new SimpleGrantedAuthority(p.getName()))
        .collect(Collectors.toList());

    Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, authorities);
    SecurityContextHolder.getContext().setAuthentication(authentication);
}

Обратите внимание, как мы правильно устанавливаем здесь полномочия аутентификации, как это обычно делается в AuthenticationProvider.

5. Заключение

Мы обсудили различные способы автоматической аутентификации пользователей после процесса регистрации.

Как всегда, полный исходный код доступен на GitHub.