Обзор и потребность в DelegatingFilterProxy весной

Обзор и потребность в DelegatingFilterProxy весной

1. обзор

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

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

2. DelegatingFilterProxyс

В Javadoc дляDelegatingFilterProxy указано, что это

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

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

2.1. Внутренняя работа DelegatingFilterProxy

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

Во время инициализацииDelegatingFilterProxy извлекаетfilter-name и извлекает bean-компонент с этим именем из Spring Application Context. Этот bean-компонент должен иметь типjavax.Servlet.Filter, i.e. «нормальный» фильтр сервлетов. Затем входящие запросы будут переданы этому компоненту фильтра.

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

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

@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 с именемapplicationFilter.

2.2. Потребность вDelegatingFilterProxy

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

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

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

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

Как описано выше,DelegatingFilterProxy - это сам фильтр сервлета, который делегирует определенный управляемый Spring bean-компонент, реализующий интерфейс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.Filter. Этот класс имеет аннотацию@Component для регистрации как bean-компонент Spring в контексте приложения. Таким образом, классDelegatingFilterProxy может найти наш класс фильтра при инициализации цепочки фильтров.

Note that the name of the Spring bean must be the same as the value in the filter-name provided during the registration of the custom filter in ApplicationInitializer class or in web.xml later , потому что классthe DelegatingFilterProxy будет искать bean-компонент фильтра с таким же именем в контексте приложения.

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

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() дляCustomFilter и отобразится подробная информация о запросе в файле журнала.

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

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

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

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