В этой статье рассмотрим, как заменить автоматически генерируемую форму ввода имени и пароля на свою собственную на Thymeleaf.
Метод formLogin() генерирует как саму форму логина, так и конечную точку обработки имени и пароля, приходящих с формы. Конечную точку, обрабатывающую по POST-запросу имя и пароль, переписывать не нужно, а вот саму html-форму, выдающуюся по методу GET /login обычно требуется заменить.
Настройка HttpSecurity
Чтобы это сделать, при настройке HttpSecurity нужно указать не просто formLogin(), как мы делали раньше, а еще .loginPage(«/login») с адресом шаблона:
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/**").hasRole("USER") .and() .formLogin().permitAll() .loginPage("/login") .loginProcessingUrl("/perform-login") .usernameParameter("user") .passwordParameter("pass") .defaultSuccessUrl("/"); }
На адрес /login (указанный в loginPage(), адрес можно указать и другой) необходимо добавить контроллер, который выдает шаблон.
Контроллер
@Controller public class LoginController { @GetMapping("/login") public String get(Model model) { model.addAttribute("title", "Форма входа"); return "login"; } }
Как видите, мы передали tittle в модель, но это необязательно — его можно сразу прописать в шаблоне.
Шаблон
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <title th:text="${title}"></title> </head> <body> <div> <form name="f" th:action="@{/perform-login}" method="post"> <fieldset> <legend>Войдите</legend> <div th:if="${param.error}" class="alert alert-error"> Неправильные имя и пароль. </div> <div th:if="${param.logout}" class="alert alert-success"> You have been logged out. </div> <label for="user">Имя</label> <input type="text" id="user" name="user"/> <label for="pass">Пароль</label> <input type="password" id="pass" name="pass"/> <div class="form-actions"> <button type="submit" class="btn">Войти</button> </div> </fieldset> </form> </div> </body> </html>
Выглядит так:
В шаблоне обратите внимание на ряд параметров, которые важны для конечной точки, обрабатывающей имя и пароль по POST-запросу.
Во-первых, это имена элементов input — они превращаются в имена параметров POST-запроса.
usernameParameter() и passwordParameter()
В автоматически генерируемой форме они называются username и password, а поскольку у нас это user и pass (см. атрибуты name):
<input type="text" id="user" name="user"/> <input type="password" id="pass" name="pass"/>
то в коде настройки HttpSecurity мы должны переопределить их в методах:
.usernameParameter("user") .passwordParameter("pass")
Эти строки есть в первом сниппете.
loginProcessingUrl()
Также переопределен loginProcessingUrl():
.loginProcessingUrl("/perform-login")
Это адрес конечной точки, куда по методу POST отправляются имя и пароль при нажатии кнопки входа. Адрес переопределен, но сама точка осталась автогенерируемой (ее генерирует Spring Security).
В шаблоне этот адрес соответствует action формы:
<form name="f" th:action="@{/perform-login}" method="post">
defaultSuccessUrl()
Наконец, можно задать
.defaultSuccessUrl("/");
это адрес страницы, куда пользователь перенаправляется при успешном входе.
Обычно он перенаправляется на ту самую закрытую страницу, куда пытался попасть (а после этого был перенаправлен на страницу входа /login).
Но если он не пытался попасть на закрытую страницу, а сразу заходил с /login, то куда-то его надо перенаправить. Вот тут и указывается этот адрес. У нас это главная страница.
Сообщение об ошибке
Наконец, если были введены неправильные имя и пароль, необходимо перенаправить пользователя на страницу с ошибкой. По умолчанию этот тот же адрес /login, но с параметром:
/login?error
В шаблоне есть обработка этого параметра:
<div th:if="${param.error}" class="alert alert-error"> Неправильные имя и пароль. </div>
Не стоит пытаться уточнять сообщение (что именно неправильное: имя или пароль). Spring Security рекомендует оставить все как есть, чтобы злоумышленник не пытался подобрать другое имя — в общем лишней информации тут давать не нужно.
Исходный код
Скачать пример полностью можно на GitHub.
Лаконично и доступно. Молодцы!
Забыли указать, что для Thymeleaf необходимо указать соответствующую зависимость в pom.xml
нет больше antMatchers()
ровно как и authorizeRequests тоже больше нет
Теперь настройка HttpSecurity:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((auth) ->
auth
.requestMatchers(«/**»).hasRole(«USER»)
)
.formLogin(login -> login.permitAll()
.loginPage(«/login»)
.loginProcessingUrl(«/perform-login»)
.usernameParameter(«user»)
.passwordParameter(«pass»)
.defaultSuccessUrl(«/»));
return http.build();
}