Рубрики
Без рубрики

Настраиваемый весенний SecurityConfigurer

Узнайте, как добавить свой собственный DSL в API Spring Security.

Автор оригинала: Loredana Crusoveanu.

1. Обзор

Поддержка конфигурации Java Spring Security предоставляет нам мощный свободный API – интерфейс для определения сопоставлений безопасности и правил для приложения.

В этой краткой статье мы увидим, как мы можем сделать этот шаг вперед и фактически определить пользовательскую конфигурацию; это продвинутый и гибкий способ введения пользовательской логики в стандартную конфигурацию безопасности.

Для нашего краткого примера здесь мы добавим функциональность, которая регистрирует ошибки для аутентифицированных пользователей в зависимости от заданного списка кодов состояния ошибок.

2. Пользовательская конфигурация безопасности

Чтобы начать определять наш конфигуратор, сначала нам нужно расширить Абстрактный Http-конфигуратор класс :

public class ClientErrorLoggingConfigurer 
  extends AbstractHttpConfigurer {

    private List errorCodes;
    
    // standard constructors
    
    @Override
    public void init(HttpSecurity http) throws Exception {
        // initialization code
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
       http.addFilterAfter(
         new ClientErrorLoggingFilter(errorCodes), 
         FilterSecurityInterceptor.class);
    }
}

Здесь основным методом, который нам нужно переопределить, является configure() метод – который содержит конфигурацию безопасности, к которой будет применяться этот конфигуратор.

В нашем примере мы зарегистрировали новый фильтр после последнего фильтра безопасности Spring. Кроме того, поскольку мы намерены регистрировать коды ошибок состояния ответа, мы добавили свойство список кодов ошибок , которое мы можем использовать для управления кодами ошибок, которые мы будем регистрировать.

Мы также можем дополнительно добавить дополнительную конфигурацию в метод init () , который выполняется перед методом configure () .

Далее давайте определим класс фильтра безопасности Spring, который мы регистрируем в нашей пользовательской реализации:

public class ClientErrorLoggingFilter extends GenericFilterBean {

    private static final Logger logger = LogManager.getLogger(
      ClientErrorLoggingFilter.class);
    private List errorCodes;

    // standard constructor

    @Override
    public void doFilter(
      ServletRequest request, 
      ServletResponse response, 
      FilterChain chain) 
      throws IOException, ServletException {
        //...

        chain.doFilter(request, response);
    }
}

Это стандартный класс фильтра Spring, который расширяет GenericFilterBean и переопределяет метод doFilter () . Он имеет два свойства, представляющие регистратор, который будет использовать для отображения сообщений, и Список кодов ошибок.

Давайте подробнее рассмотрим метод doFilter() :

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null) {
    chain.doFilter(request, response);
    return;
}
int status = ((HttpServletResponse) response).getStatus();
if (status < 400 || status >= 500) {
    chain.doFilter(request, response);
    return;
}
if (errorCodes == null) {
    logger.debug("User " + auth.getName() + " encountered error " + status);
} else {
    if (errorCodes.stream().anyMatch(s -> s.value() == status)) {
        logger.debug("User " + auth.getName() + " encountered error " + status);
    }
}

Если код состояния является кодом состояния ошибки клиента, то есть от 400 до 500, мы проверим список коды ошибок .

Если это пустое значение, то мы отобразим любой код состояния ошибки клиента. В противном случае мы сначала проверим, является ли код ошибки частью данного Списка кодов состояния.

3. Использование настроенного пользователем

Теперь, когда у нас есть собственный API, мы можем добавить его в конфигурацию безопасности Spring, определив компонент, а затем используя метод apply () /HttpSecurity:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          //...
          .and()
          .apply(clientErrorLogging());
    }

    @Bean
    public ClientErrorLoggingConfigurer clientErrorLogging() {
        return new ClientErrorLoggingConfigurer() ;
    }
}

Мы также можем определить компонент с определенным списком кодов ошибок, которые мы хотим зарегистрировать:

@Bean
public ClientErrorLoggingConfigurer clientErrorLogging() {
    return new ClientErrorLoggingConfigurer(Arrays.asList(HttpStatus.NOT_FOUND)) ;
}

И это все! Теперь наша конфигурация безопасности будет включать пользовательский фильтр и отображать сообщения журнала.

Если мы хотим, чтобы пользовательские настройки были добавлены по умолчанию, мы можем использовать файл META-INF/spring.factories :

org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = com.baeldung.dsl.ClientErrorLoggingConfigurer

И чтобы отключить его вручную, мы можем использовать метод disable() :

//...
.apply(clientErrorLogging()).disable();

4. Заключение

В этом кратком руководстве мы сосредоточились на расширенной функции поддержки конфигурации безопасности Spring – мы видели, как определить наш собственный пользовательский SecurityConfigurer .

Как всегда, полный исходный код примера можно найти на GitHub .