Spring Security для борьбы с галантерейными товарами: нестандартная обработка исключений

Spring Boot

1. Введение

Я был очень занят в последнее время, и мне трудно найти время, чтобы продолжить обновлениеПрактичная серия галантереи Spring Security. Как раз вовремя для проекта сегодняSpring SecurityЕсли вам нужно обрабатывать исключения аутентификации и авторизации, поделитесь ими.

2. Исключения в Spring Security

Spring SecurityИсключения в базе данных в основном делятся на две категории: одна — исключения аутентификации, а другая — исключения, связанные с авторизацией.

2.1 AuthenticationException

AuthenticationExceptionЭто исключение возникает при возникновении ошибки во время аутентификации пользователя. Основные подклассы показаны на рисунке:

AuthenticationException.png

Согласно информации на рисунке, системный пользователь не существует, заблокирован, сертификат недействителен, пароль неверный и другие исключения в процессе аутентификации вызваныAuthenticationExceptionиметь дело с.

2.2 AccessDeniedException

AccessDeniedExceptionВ основном это исключение, возникающее, когда пользователю отказано в доступе к защищенному ресурсу. такой жеAuthenticationExceptionОн также предоставляет некоторые конкретные подклассы. Как показано ниже:

AccessDeniedException.png

AccessDeniedExceptionПодклассы относительно немногочисленны, в основномCSRFСвязанные исключения и исключения службы авторизации.

3. Требования к статусу HTTP для аутентификации и авторизации

HttpПротокол также определяет результат ответа аутентификации и авторизации.

3.1 401 Неавторизованный статус

Ошибка HTTP 401 — неавторизованныйОбычно это сообщение об ошибке указывает на то, что сначала необходимо войти в систему (ввести правильное имя пользователя и пароль). Если вы только что ввели эту информацию, вы сразу же увидите401Ошибка означает, что одно или оба ваших имени пользователя и пароля недействительны по какой-либо причине (опечатка, имя пользователя временно отключено, учетная запись заблокирована, учетные данные недействительны и т. д.). Короче говоря, аутентификация не удалась. На самом деле он точно соответствует нашему вышеAuthenticationException.

3.2 403 Статус отказа

Ошибка HTTP 403 — ЗапрещеноЭта ошибка указывает на то, что у вас нет разрешения на доступ к ресурсу с ограниченным доступом. Сервер понимает запрос, но отказывается выполнять задачу, и запрос не должен повторно отправляться на сервер. И сервер хочет, чтобы клиент знал, почему у него нет разрешения на доступ к конкретному ресурсу, сервер должен описать причину отказа в возвращаемой информации. В общем случае покажем причины более расплывчато. Эта ошибка соответствует нашей вышеAccessDeniedException.

4. Обработка исключений в Spring Security

мы вSpring SecurityВ серии актуальных галантереиЗапись пользовательского класса конфигурации WebSecurityConfigurerAdapterупоминается в статьеHttpSecurityкоторый предоставилexceptionHandling()Методы используются для обеспечения обработки исключений. Этот метод конструируетExceptionHandlingConfigurerКласс конфигурации обработки исключений. Класс конфигурации предоставляет два служебных интерфейса:

  • AuthenticationEntryPointЭтот класс используется для унифицированной обработкиAuthenticationExceptionаномальный
  • AccessDeniedHandlerЭтот класс используется для унифицированной обработкиAccessDeniedExceptionаномальный

Нам нужно только реализовать и настроить эти два класса обработки исключений для достиженияSpring SecurityУнифицированная настраиваемая обработка исключений, связанных с аутентификацией и авторизацией.

4.1 Реализовать AuthenticationEntryPoint

отjsonИнформационный ответ.

 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.http.MediaType;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.AuthenticationEntryPoint;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.HashMap;
 
 /**
  * @author dax
  * @since 2019/11/6 22:11
  */
 public class SimpleAuthenticationEntryPoint implements AuthenticationEntryPoint {
     @Override
     public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
 
         //todo your business
         HashMap<String, String> map = new HashMap<>(2);
         map.put("uri", request.getRequestURI());
         map.put("msg", "认证失败");
         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
         response.setCharacterEncoding("utf-8");
         response.setContentType(MediaType.APPLICATION_JSON_VALUE);
         ObjectMapper objectMapper = new ObjectMapper();
         String resBody = objectMapper.writeValueAsString(map);
         PrintWriter printWriter = response.getWriter();
         printWriter.print(resBody);
         printWriter.flush();
         printWriter.close();
     }
 }

4.2 Реализация AccessDeniedHandler

такой же какjsonИнформационный ответ.

 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.http.MediaType;
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.web.access.AccessDeniedHandler;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.HashMap;
 
 /**
  * @author dax
  * @since 2019/11/6 22:19
  */
 public class SimpleAccessDeniedHandler implements AccessDeniedHandler {
     @Override
     public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
         //todo your business
         HashMap<String, String> map = new HashMap<>(2);
         map.put("uri", request.getRequestURI());
         map.put("msg", "认证失败");
         response.setStatus(HttpServletResponse.SC_FORBIDDEN);
         response.setCharacterEncoding("utf-8");
         response.setContentType(MediaType.APPLICATION_JSON_VALUE);
         ObjectMapper objectMapper = new ObjectMapper();
         String resBody = objectMapper.writeValueAsString(map);
         PrintWriter printWriter = response.getWriter();
         printWriter.print(resBody);
         printWriter.flush();
         printWriter.close();
     }
 }

4.3 Консультации по личной практике

Собственно, лично я рекомендуюHttpкоды состояния возвращаются200И поместите статус 401 в метаинформациюMapвернуться в. Поскольку код состояния исключения будет отображаться на стороне браузера какerrorпоказывать. Пока мы можем поймать401и403Можно определить, является ли это проблемой аутентификации или проблемой авторизации.

4.4 Конфигурация

После реализации двух вышеуказанных интерфейсов нам нужно толькоWebSecurityConfigurerAdapterизconfigure(HttpSecurity http)метод можно настроить. Ниже приведены соответствующие фрагменты конфигурации:

 http.exceptionHandling().accessDeniedHandler(new SimpleAccessDeniedHandler()).authenticationEntryPoint(new SimpleAuthenticationEntryPoint())

5. Резюме

Сегодня мыSpring SecurityОбработка исключений объясняется в . Реализована настраиваемая обработка исключений аутентификации и настраиваемая обработка исключений авторизации соответственно. СвязанныйDEMOВы можете следить за публичной учетной записью WeChat:FelordcnОтветитьss07Получать.

关注公众号:Felordcn获取更多资讯

Личный блог: https://felord.cn