«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.