Какая точка Spring MVC DelegatingFilterProxy?

Я вижу это в своем приложении Spring MVC web.xml:

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

Я пытаюсь выяснить, почему он существует и нужен ли он на самом деле.

Я нашел это объяснение в документации Spring, но это не помогло мне разобраться в этом:

Кажется, предполагается, что этот компонент является "связующим звеном" между сервлетами, определенными в web.xml, и компонентами, определенными в Spring applicationContext.xml.

7.1 DelegatingFilterProxy

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

При использовании DelegatingFilterProxy вы увидите нечто подобное в файле web.xml:

<filter>
   <filter-name>myFilter</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
   <filter-name>myFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Обратите внимание, что фильтр на самом деле является DelegatingFilterProxy, а не классом, который фактически реализует логику фильтра. DelegatingFilterProxy выполняет делегирование методов Filter через bean-компонент, который получается из контекста приложения Spring. Это позволяет компоненту воспользоваться поддержкой жизненного цикла контекста веб-приложения Spring и гибкостью настройки. Бин должен реализовывать javax.servlet.Filter, и у него должно быть то же имя, что и в элементе имени фильтра. Прочитайте Javadoc для DelegatingFilterProxy для получения дополнительной информации

Итак, если я возьму это из моего web.xml, что произойдет? Мои сервлеты не смогут связаться с контейнером Spring? **

Ответ 1

Здесь какая-то магия, но в конце все это детерминированная программа.

DelegatingFilterProxy - это фильтр, как было описано выше, целью которого является " делегирование Spring -установленного bean, реализующего интерфейс фильтра), то есть он находит bean (" target bean "или" делегат") в вашем контексте приложения Spring и вызывает его. Как это возможно? Поскольку этот bean реализует javax.servlet.Filter, вызывается его метод doFilter.

Какой bean вызывается? DelegatingFilterProxy "Поддерживает" targetBeanName "[...], указывая имя целевого bean в контексте приложения Spring.

Как вы видели в своем web.xml, что имя bean - "springSecurityFilterChain" .

Итак, в контексте веб-приложения фильтр создает экземпляр bean, называемый "springSecurityFilterChain" в контексте вашего приложения, а затем делегирует его с помощью метода doFilter().

Помните, что ваш контекст приложения определен всеми файлами ALL APPLICATION-CONTEXT (XML). Например: applicationContext.xml И applicationContext-security.xml.

Итак, попробуйте найти bean, называемый "springSecurityFilterChain" в последнем...

... и , возможно, вы не можете (например, если вы следовали учебному курсу или если вы настроили безопасность с помощью Roo)

Вот волшебство: есть новый элемент для настройки безопасности, что-то вроде

<http auto-config="true" use-expressions="true"> 

поскольку это разрешено http://www.springframework.org/schema/security/spring-security-3.0.xsd, сделает трюк.

Когда Spring загружает контекст приложения с помощью файлов XML, если он находит элемент, он попытается настроить защиту HTTP, то есть стек фильтра и защищенные URL-адреса, и зарегистрировать FilterChainProxy с именем "springSecurityFilterChain".

В качестве альтернативы вы можете определить bean классическим способом, а именно:

<beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">

Но это менее рекомендуется, так как вам нужно выполнить большую конфигурацию (все фильтры, которые вы собираетесь использовать, и их более десятка)

Ответ 2

Знаете ли вы, что такое сервлет Filter и как он работает? Это очень полезная часть спецификации Servlet, позволяющая применять AOP-подобные концепции для обслуживания HTTP-запросов. Многие фреймворки используют реализации фильтров для разных вещей, и нередко можно найти их собственные реализации, потому что они очень просты в написании и полезны. В приложении Spring большинство материалов, которые может выполнять ваше приложение, находится в Spring beans. Однако экземпляр фильтра управляется контейнером сервлета. Контейнер создает, инициализирует и уничтожает его. Однако Servlet Spec не требует какой-либо интеграции Spring, поэтому у вас осталась действительно полезная концепция (Filters) без удобного способа привязки ее к вашему приложению Spring и beans, которые делают работа.

Введите делегациюFilterProxy. Вы пишете реализацию фильтра и делаете его Spring bean, но вместо добавления своего собственного класса Filter в файл web.xml вы используете DelegatingFilterProxy и указываете ему имя bean вашего фильтра в Spring контекст. (Если вы явно не указываете имя, оно использует "имя фильтра".) Затем во время выполнения ДелегированиеFilterProxy обрабатывает сложность поиска реальной реализации - той, которую вы написали и настроили в Spring, и запросов на маршрутизацию к нему. Таким образом, во время выполнения, как будто вы указали свой фильтр в web.xml, но вы получаете возможность подключить его, как и любой другой Spring bean.

Если вы выберете это фильтрационное отображение из вашего web.xml, все будет продолжать работать, но ни один из ваших URL-адресов не будет защищен. (Предположим, что имя springSecurityFilterChain точно описывает, что он делает.) Это потому, что это сопоставление фильтрует каждый входящий запрос и передает его фильтру безопасности, который определен в вашем контексте Spring.

Ответ 3

Что такое сервлет-фильтры?

Сервлет-фильтры - это, в общем, концепция Java WebApp. Вы можете иметь сервлет-фильтры в любом веб-приложении, независимо от того, используете ли вы фреймворк Spring в своем приложении.

Эти фильтры могут перехватывать запросы до того, как они достигнут целевого сервлета. Вы можете реализовать общие функции, такие как авторизация, в сервлет-фильтрах. После внедрения вы можете настроить фильтр в вашем web.xml для применения к определенному сервлету, конкретным шаблонам URL-адресов запроса или всем шаблонам url.

Где используются фильтры сервлетов?

Современные веб-приложения могут иметь десятки таких фильтров. Такие функции, как авторизация, кеширование, управление сеансом ORM и инъекция зависимостей, часто реализуются с помощью фильтра сервлетов. Все эти фильтры необходимо зарегистрировать в web.xml.

Создание экземпляров сервлет-фильтров - без Spring Framework

Контейнер сервлета создает экземпляры фильтров, объявленных в web.xml, и вызывает их в соответствующее время (т.е. при обслуживании запросов сервлета). Теперь, если вы похожи на поклонников Injection (DI) Dependency Injection (DI), вы, вероятно, скажете, что создание экземпляров - это то, что делает моя инфраструктура DI (Spring) лучше. Не могу ли я получить фильтры сервлета, созданные с помощью Spring, чтобы они были пригодны ко всем возможностям DI?

DelegatingFilterProxy, так что Spring создает экземпляры вашего фильтра

Здесь находится DelegatingFilterProxy. DelegatingFilterProxy - это искажение интерфейса javax.servlet.Filter, предоставляемого Spring Framework. После настройки DelegatingFilterProxy в web.xml вы можете объявить фактический beans, который выполняет фильтрацию в конфигурации Spring. Таким образом, Spring создает экземпляры beans, которые выполняют фактическую фильтрацию, и вы можете использовать DI для настройки этих beans.

Обратите внимание, что вам нужно только одно объявление DelegatingFilterProxy в web.xml, но вы можете иметь несколько фильтров bean в цепочке приложений.

Ответ 4

Дело в том, что фильтры сервлетов управляются контейнером сервлета, а не spring. И вам может понадобиться вставить некоторые компоненты spring в ваши фильтры.

Итак, если вам нужно что-то вроде:

public class FooFilter {

    @Inject
    private FooService service;

    public void doFilter(....) { .. }

}

тогда вам понадобится прокси-сервер делегирования фильтра.

Ответ 5

Ты прав насчет "клея". Как написано в JavaDocs FilterChainProxy:

FilterChainProxy связан с цепочкой фильтров контейнера сервлетов, добавив стандартное объявление Spring DelegatingFilterProxy в файл приложения web.xml.

Пожалуйста, см. раздел FIlterChainProxy в блоге Позади Spring Защищенного пространства имен для отличного объяснения.

Ответ 6

Я был озадачен "springSecurityFilterChain" в web.xml и нашел этот ответ в документе безопасности весенне-полевого плана:

Элемент <http> инкапсулирует конфигурацию безопасности для веб-уровня вашего приложения. > Он создает FilterChainProxy bean с именем "springSecurityFilterChain", который поддерживает стек > фильтров безопасности, которые составляют конфигурацию веб-безопасности [19]. Некоторые основные фильтры всегда создаются, а другие добавляются в стек в зависимости от атрибутов дочерних элементов, которые присутствуют. Позиции стандартных фильтров фиксированы (см. Таблицу заказа фильтра в предложении > namespace), удалив общий источник ошибок с предыдущими версиями фреймворкa > , когда пользователям пришлось явно настроить цепочку фильтров в файле FilterChainProxy bean. Вы можете, конечно, по-прежнему делать это, если вам нужен полный контроль над конфигурацией.

Вот ссылка http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-namespace.html

Ответ 7

Это было долгое время, но у меня был тот же вопрос, и я нашел это: https://www.javacodegeeks.com/2013/11/spring-security-behind-the-scenes.html

Я попытался запустить мой проект безопасности spring, удалив соответствующий фильтр, а также добавив его. Я обнаружил, что если мы добавим фильтр, только тогда вызов будет перенаправлен на требуемую страницу входа, как определено в конфигурации spring -security.

Следовательно, соглашаясь на ответ @Ryan.