Spring Security для борьбы с галантерейными товарами: реализация пользовательского выхода из системы

Spring Boot задняя часть

logout.png

1. Введение

Предыдущая статьяSpring Securityвсе встроенноеFilterпредставил. Сегодня мы увидим, как безопасно выйти из приложения.

2. Что мы сделали после входа в Spring Security

Мы должны это выяснить! Как правило, после входа в систему сервер выдает пользователю учетные данные. Есть два распространенных:

  • на основеSessionКлиент сэкономитcookieчтобы сохранитьsessionId, сервер сохраняетSession.
  • на основеtokenКлиент сохраняетtokenстрока, сервер сохранит строку в кеше, чтобы проверить этоtokenИнформация.

2. Что нам нужно сделать, чтобы выйти из системы

  1. Текущий статус входа пользователя недействителен. Это требует от нас очистки пользовательского состояния сервера.
  2. Регистрация из интерфейса входа не являетсяpermitAllНосите только учетные данные соответствующих пользователей до выхода.
  3. Верните результат выхода запрашивающей стороне.
  4. После выхода из системы пользователь может аутентифицировать пользователя, снова войдя в систему.

3. Выйдите из Spring Security

Далее, давайте проанализируем и попрактикуемсяКак настроить логику выхода. Сначала нам нужно понятьLogoutFilter.

3.1 LogoutFilter

пройти черезSpring Security актуальные боевые галантерейные товары: встроенный фильтр для полного анализаМы знаем, что логика выхода контролируется фильтромLogoutFilterвыполнить. Он содержит свойства трех типов интерфейса:

  1. RequestMatcher logoutRequestMatcherЭто используется для перехвата запросов на выход.URL
  2. LogoutHandler handlerКонкретная логика, используемая для обработки выхода
  3. 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