Как подключиться к процессу аутентификации Spring Security?

Сейчас у меня такая тривиальная конфигурация:

// Kotlin code
override fun configure(http: HttpSecurity) {
    http
        .formLogin()
        .loginPage("/entry")
        .loginProcessingUrl("/auth")
        .usernameParameter("usr")
        .passwordParameter("pwd")
        .defaultSuccessUrl("/", true)
        .failureHandler { request, response, exception -> 
            // Can't figure out what to enter here (see below).
        }
}

Если аутентификация не удалась, у меня есть два требования:

  1. Мгновенное сообщение об ошибке в сеансе (избегая параметра «ошибка» в строке запроса). Кажется, я не могу ввести RedirectAttributes в эту лямбду; есть ли обходной путь?

  2. Я хочу отправить обратно логин (но не пароль), который пользователь ввел перед отправкой формы входа, чтобы повторно заполнить поле. Как я могу это сделать?

0
0
193
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я смог понять это.

@Configuration
@EnableWebSecurity
class SecurityConfig: WebSecurityConfigurerAdapter() {
    override fun configure(http: HttpSecurity) {
        http
            .formLogin()
            .loginPage("/entry")
            .loginProcessingUrl("/auth")
            .usernameParameter("usr")
            .passwordParameter("pwd")
            .defaultSuccessUrl("/", true)
            .failureHandler { request, response, _ ->
                request.session.setAttribute("loginError", "Login Error!")
                request.session.setAttribute("failedUsername", request.getParameter("usr"))
                response.sendRedirect("/entry")
            }
    }
}

Затем вам необходимо настроить контроллер входа в систему, чтобы настроить обслуживание формы входа:

@Controller
@RequestMapping("/entry")
internal class LoginController {
    @GetMapping
    fun getLoginForm(session: HttpSession, model: Model): String {
        if (session.getAttribute("loginError") != null) {
            model.addAttribute("loginError", "Login Error!")
            session.removeAttribute("loginError")
            model.addAttribute("failedUsername", session.getAttribute("failedUsername"))
            session.removeAttribute("failedUsername")
        }
        return "login"
    }
}

Затем вы можете использовать атрибуты модели loginError и failedUsername в своих шаблонах:

<div th:if = "${loginError}">Incorrect login/password</div>
<!-- ... -->
<input type = "text" name = "usr" th:value = "${failedUsername}">

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

В результате теперь в URL-адресе страницы нет ?error, и пользователю не требуется повторно вводить имя пользователя.

Другие вопросы по теме