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 .