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 .