1. Введение
Предыдущая статьяSpring Securityвсе встроенноеFilterпредставил. Сегодня мы увидим, как безопасно выйти из приложения.
2. Что мы сделали после входа в Spring Security
Мы должны это выяснить! Как правило, после входа в систему сервер выдает пользователю учетные данные. Есть два распространенных:
- на основе
SessionКлиент сэкономитcookieчтобы сохранитьsessionId, сервер сохраняетSession. - на основе
tokenКлиент сохраняетtokenстрока, сервер сохранит строку в кеше, чтобы проверить этоtokenИнформация.
2. Что нам нужно сделать, чтобы выйти из системы
- Текущий статус входа пользователя недействителен. Это требует от нас очистки пользовательского состояния сервера.
- Регистрация из интерфейса входа не является
permitAllНосите только учетные данные соответствующих пользователей до выхода. - Верните результат выхода запрашивающей стороне.
- После выхода из системы пользователь может аутентифицировать пользователя, снова войдя в систему.
3. Выйдите из Spring Security
Далее, давайте проанализируем и попрактикуемсяКак настроить логику выхода. Сначала нам нужно понятьLogoutFilter.
3.1 LogoutFilter
пройти черезSpring Security актуальные боевые галантерейные товары: встроенный фильтр для полного анализаМы знаем, что логика выхода контролируется фильтромLogoutFilterвыполнить. Он содержит свойства трех типов интерфейса:
-
RequestMatcher logoutRequestMatcherЭто используется для перехвата запросов на выход.URL -
LogoutHandler handlerКонкретная логика, используемая для обработки выхода -
LogoutSuccessHandler logoutSuccessHandlerЛогика, выполняемая после успешного выхода
Мы можем реализовать нашу пользовательскую логику выхода, реализовав три вышеуказанных интерфейса.
3.2 LogoutConfigurer
Обычно мы не работаем напрямуюLogoutFilter, но черезLogoutConfigurerнастроитьLogoutFilter. ты можешь пройтиHttpSecurity#logout()метод для инициализацииLogoutConfigurer. Далее, давайте сделаем это на практике.
3.2.1 Реализация пользовательского URL-адреса запроса на выход из системы
LogoutConfigurerпри условииlogoutRequestMatcher(RequestMatcher logoutRequestMatcher),logoutUrl(Sring logoutUrl)Два способа определить запрос на выход из системыURL. Они работают одинаково, вы можете выбрать один из них.
3.2.2 Обработка специальной логики
по умолчаниюSpring Securityоснован наSessionиз.LogoutConfigurerНекоторые прямые конфигурации предоставляются в соответствии с вашими потребностями. следующее:
-
clearAuthentication(boolean clearAuthentication)Очищать ли информацию об аутентификации текущего пользователя при выходе из системы -
deleteCookies(String... cookieNamesToClear)удалить указанныйcookies -
invalidateHttpSession(boolean invalidateHttpSession)удалить лиHttpSession
Если вышеуказанное не соответствует вашим потребностям, вам необходимо настроитьLogoutHandler.
3.2.3 Логика успешного выхода
-
logoutSuccessUrl(String logoutSuccessUrl)После успешного выхода вы будете перенаправлены на этотURL,Вы можете написать контроллер для окончательного возврата, но вам нужна поддержкаGETзапрос и анонимный доступ. пройти черезsetDefaultTargetUrlметод, внедренный вLogoutSuccessHandler -
defaultLogoutSuccessHandlerFor(LogoutSuccessHandler handler, RequestMatcher preferredMatcher)используется для построения по умолчаниюLogoutSuccessHandlerМы можем добиться от разных, добавив несколькоURLExit выполняет другую логику. -
LogoutSuccessHandler logoutSuccessHandlerАбстрактный корневой интерфейс для выполнения логики после успешного выхода.
3.3 Битва за выход и вход в Spring Security
Теперь между интерфейсом и сервером больше разделений, а после выхода возвращается json. И только пользователь находится в сети, чтобы выйти из системы. В противном случае операция выхода не может быть выполнена. Мы реализуемLogoutHandlerиLogoutSuccessHandlerИнтерфейс это программный способ настройки. запрос на отказurlвсе еще проходитLogoutConfigurer#logoutUrl(String logoutUrl)определять.
3.3.1 Пользовательский обработчик выхода из системы
Информация аутентификации по умолчанию очищается (invalidateHttpSession) и аннулирование сеанса (invalidateHttpSession) уже обеспечивается встроеннымSecurityContextLogoutHandlerЧто нужно сделать. наш обычайLogoutHandlerБудет вSecurityContextLogoutHandlerвыполнить.
@Slf4j
public class CustomLogoutHandler implements LogoutHandler {
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
User user = (User) authentication.getPrincipal();
String username = user.getUsername();
log.info("username: {} is offline now", username);
}
}
Вышеупомянутое то, что мы достиглиLogoutHandler. мы можем начать сlogoutметодauthenticationПолучить текущую информацию о пользователе в переменной. Вы можете использовать это для достижения желаемого бизнеса. Например, записывать время выхода пользователя из системы, IP-адрес и т. д.
3.3.2 Пользовательский обработчик LogoutSuccessHandler
Если мы реализуем пользовательскийLogoutSuccessHandlerнет необходимости устанавливатьLogoutConfigurer#logoutSuccessUrl(String logoutSuccessUrl). Процессор ответит внешнему интерфейсу после обработки. Вы можете перенаправить на другие контроллеры. Редирект на страницу входа, вы также можете реализовать другие самостоятельноMediaType, возможноjsonили страница
@Slf4j
public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
User user = (User) authentication.getPrincipal();
String username = user.getUsername();
log.info("username: {} is offline now", username);
responseJsonWriter(response, RestBody.ok("退出成功"));
}
private static void responseJsonWriter(HttpServletResponse response, Rest rest) throws IOException {
response.setStatus(HttpServletResponse.SC_OK);
response.setCharacterEncoding("utf-8");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
ObjectMapper objectMapper = new ObjectMapper();
String resBody = objectMapper.writeValueAsString(rest);
PrintWriter printWriter = response.getWriter();
printWriter.print(resBody);
printWriter.flush();
printWriter.close();
}
}
3.3.4 Конфигурация Spring Security для пользовательского выхода
Для простоты отладки я закомментировал нашРеализован пользовательский логин, вы можете пройтиhttp:localhost:8080/loginчтобы войти, тоhttp:localhost:8080/logoutПробный выход.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.cors()
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
// .addFilterBefore(preLoginFilter, UsernamePasswordAuthenticationFilter.class)
// 登录
.formLogin().loginProcessingUrl(LOGIN_PROCESSING_URL).successForwardUrl("/login/success").failureForwardUrl("/login/failure")
.and().logout().addLogoutHandler(new CustomLogoutHandler()).logoutSuccessHandler(new CustomLogoutSuccessHandler());
}
4. Резюме
В этой статье мы достиглиSpring SecurityПользовательская логика выхода в . Относительно просто, вы можете реализовать логику выхода в соответствии с потребностями вашего бизнеса. Если у вас есть какие-либо вопросы, пожалуйста, подпишитесь на официальный аккаунт:FelordcnЧтобы задать вопросы в приват. Соответствующие коды DEMO также могут сопровождаться ответомss04Получать.
关注公众号:Felordcn获取更多资讯
Личный блог: https://felord.cn