Как программно аутентифицировать пользователя по сессии Spring
Я знаю, что в спринг уже встроен такой механизм при отправке запроса по маршруту /login или другому выбранному в WebSecurityConfig'e. Также если брать Vaadin, то в нём есть специальный компонент LoginForm, аутентификация через него описана тут. Как вы понимаете мне не нужен стандартный механизм, так как я хочу:
- сделать одинаково другой дизайн как для страницы регистрации так и для входа.
- добавить что-то типа прохождения капчи или отправки кода для проверки подлинности на электронную почту.
Одним словом - кастомизировать механизм входа.
Как программно аутентифицировать пользователя?
Я пробовал такое решение:
try {
Authentication authentication = new UsernamePasswordAuthenticationToken(fieldMail.getValue(), fieldPassword.getValue()); // mail и password
Authentication authenticatedUser = authenticationManager.authenticate(authentication); // authenticationManager был получен через @Autowired из бина
if (authenticatedUser.isAuthenticated()) { // проверка на аутентифицированность
System.out.println("One user authenticated");
UI.getCurrent().navigate("x1/cabinet"); // переходим в кабинет пользователя
}
credentialsErrorText.setVisible(false); // показываем ошибку данных входа
}catch (BadCredentialsException e){
credentialsErrorText.setVisible(true); // показываем ошибку данных входа
}
Bean:
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration){
try {
return authenticationConfiguration.getAuthenticationManager();
}catch(Exception e){
System.out.println(e.getMessage());
return null;
}
}
Но не помогло. Удивительно, но ошибки нет! Когда я ввожу действительные данные и нажимаю - войти, то в консоли пишет, что юзер в базе данных найден и успешно получен, да ещё и аутентифицирован:
user found
from user
One user authenticated
Но на сайте это не отображается, так как при нажатии "войти" меня на миллисекунду отправляет в кабинет, но потом снова возвращает на страницу входа как будто я ещё не аутентифицировался, так как в кабинет можно только аутентифицированным пользователям (@PermitAll).
PS. Продолжая поиски решения я пришёл к такому коду:
try {
SecurityUser principal = new SecurityUser(
fieldPassword.getValue().toString(),fieldMail.getValue().toString(), true,
new HashSet<>(){{
add(new SimpleGrantedAuthority("User"));
}});
Authentication authentication = new UsernamePasswordAuthenticationToken(
principal,
new Credentials() {
@Override
public Principal getUserPrincipal() {
return (Principal) principal;
}
@Override
public String getPassword() {
return fieldPassword.getValue().toString();
}
},principal.getAuthorities());
Authentication authenticatedUser = authenticationManager.authenticate(authentication);
if (authenticatedUser.isAuthenticated()) {
System.out.println("One user authenticated");
UI.getCurrent().navigate("x1/cabinet");
}
}catch (BadCredentialsException e){
e.printStackTrace();
Notification.show("CredentialsError");
}
В итоге при верных входных данных срабатывает catch BadCredentialsException при вызове метода authenticationManager.authenticate()