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

Обзор и необходимость делегирования Filterproxy весной

Узнайте, как использовать Spring’s DelegatingFilterProxy для реализации фильтров сервлетов

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

1. Обзор

DelegatingFilterProxy – это фильтр сервлетов, который позволяет передавать управление классам Filter , имеющим доступ к контексту приложения Spring. Весенняя безопасность в значительной степени зависит от этой техники.

В этом уроке мы рассмотрим это подробно.

2. Делегирование filterproxy

Javadoc для DelegatingFilterProxy утверждает, что это

Прокси-сервер для стандартного фильтра сервлетов, делегируемый управляемому Spring компоненту, реализующему интерфейс фильтра.

При использовании фильтров сервлетов нам, очевидно, необходимо объявить их как класс фильтров в нашей Java-конфигурации или web.xml , в противном случае контейнер сервлета будет игнорировать их. Spring’s DelegatingFilterProxy обеспечивает связь между web.xml и контекст приложения.

2.1. Внутренняя работа делегирования Filterproxy

Давайте посмотрим, как DelegatingFilterProxy передает управление нашему Spring bean.

Во время инициализации DelegatingFilterProxy извлекает имя фильтра и извлекает компонент с этим именем из контекста приложения Spring. Этот компонент должен иметь тип javax.Servlet.Фильтр, т. Е. “обычный” фильтр сервлета. Затем входящие запросы будут переданы в этот компонент фильтра.

Короче говоря, Делегирование Filterproxy доФильтр() метод делегирует все вызовы компоненту Spring, позволяя нам использовать все функции Spring в нашем компоненте фильтра.

Если мы используем конфигурацию на основе Java, наша регистрация фильтра в Инициализаторе приложения будет определена как:

@Override
protected javax.servlet.Filter[] getServletFilters() {
    DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy();
    delegateFilterProxy.setTargetBeanName("applicationFilter");
    return new Filter[]{delegateFilterProxy};
}

Если мы используем XML, то в web.xml файл:


    applicationFilter
    org.springframework.web.filter.DelegatingFilterProxy

Это означает, что любой запрос может быть сделан для прохождения через фильтр, определенный как Spring bean с именем applicationFilter .

2.2. Необходимость делегирования Filterproxy

DelegatingFilterProxy – это класс в веб-модуле Spring. Он предоставляет функции для того, чтобы HTTP-вызовы проходили через фильтры до достижения фактического места назначения. С помощью DelegatingFilterProxy, класс, реализующий javax.Servlet.Фильтр интерфейс может быть подключен к цепочке фильтров.

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

Делегирование Filterproxy также использует вызов определенных или нескольких фильтров в соответствии с путями URI запроса, предоставляя конфигурацию в контексте приложения Spring или в web.xml.

3. Создание пользовательского фильтра

Как описано выше, DelegatingFilterProxy -это сам фильтр сервлета, который делегирует определенный управляемый пружиной компонент, реализующий интерфейс Filter .

В следующих нескольких разделах мы создадим пользовательский фильтр и настроим его с помощью конфигурации на основе Java и XML.

3.1. Класс фильтра

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

Давайте сначала создадим пользовательский класс фильтра:

@Component("loggingFilter")
public class CustomFilter implements Filter {

    private static Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);

    @Override
    public void init(FilterConfig config) throws ServletException {
        // initialize something
    }

    @Override
    public void doFilter(
      ServletRequest request, ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {
 
        HttpServletRequest req = (HttpServletRequest) request;
        LOGGER.info("Request Info : " + req);
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // cleanup code, if necessary
    }
}

CustomFilter реализует javax.Servlet.Фильтр . Этот класс имеет аннотацию @Component для регистрации в качестве компонента Spring в контексте приложения. Таким образом, класс DelegatingFilterProxy может найти наш класс фильтра при инициализации цепочки фильтров.

Обратите внимание, что имя компонента Spring должно совпадать со значением в filter-name , предоставленным при регистрации пользовательского фильтра в ApplicationInitializer классе или в web.xml позже потому что класс DelegatingFilterProxy будет искать компонент фильтра с точно таким же именем в контексте приложения.

Если он не может найти компонент с таким именем, он вызовет исключение при запуске приложения.

3.2. Настройка фильтра с помощью конфигурации Java

Чтобы зарегистрировать пользовательский фильтр с помощью конфигурации Java, нам нужно переопределить getServletFilters() метод AbstractAnnotationConfigDispatcherServletInitializer :

public class ApplicationInitializer 
  extends AbstractAnnotationConfigDispatcherServletInitializer {
    // some other methods here
 
    @Override
    protected javax.servlet.Filter[] getServletFilters() {
        DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy();
        delegateFilterProxy.setTargetBeanName("loggingFilter");
        return new Filter[]{delegateFilterProxy};
    }
}

3.3. Настройка фильтра с помощью web.xml

Давайте посмотрим, как конфигурация фильтра в web.xml похоже на:


    loggingFilter
    org.springframework.web.filter.DelegatingFilterProxy


    loggingFilter
    /*

Аргумент filter-class имеет тип DelegatingFilterProxy , а не класс фильтра, который мы создали. Если мы запустим этот код и нажмем любой URL-адрес, то doFilter() метод Пользовательского фильтра будет выполнен и отобразит информацию о запросе в файле журнала.

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

В этой статье мы рассмотрели, как работает DelegatingFilterProxy и как его использовать.

Spring Security широко использует DelegatingFilterProxy для защиты вызовов веб-API и ресурсов от несанкционированного доступа.

Исходный код доступен на GitHub .