Spring MVC의 DelegatingFilterProxy의 요점은 무엇입니까?


120

내 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 Bean이므로 Spring의 풍부한 종속성 주입 기능 및 라이프 사이클 인터페이스를 활용할 수 있습니다. Spring DelegatingFilterProxyweb.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논리를 구현하는 클래스가 아니라 실제로입니다. DelegatingFilterProxySpring 애플리케이션 컨텍스트에서 얻은 빈에 필터의 메서드를 위임하는 것이 무엇입니까? 이를 통해 Bean은 Spring 웹 애플리케이션 컨텍스트 라이프 사이클 지원 및 구성 유연성의 이점을 누릴 수 있습니다. Bean은 구현 javax.servlet.Filter해야하며 filter-name 요소의 이름과 동일한 이름을 가져야합니다. 자세한 정보 는 DelegatingFilterProxy에 대한 Javadoc을 읽으십시오.

그래서, 이것을 내 web.xml에서 꺼내면 어떻게 될까요? 내 서블릿이 Spring 컨테이너와 통신 할 수 없습니까? **

답변:


127

여기에는 일종의 마법이 있지만 결국 모든 것이 결정 론적 프로그램입니다.

DelegatingFilterProxy는 누구의 목표 "있다가 위에서 설명 된 바와 같이 필터입니다 구현 필터 인터페이스하는 Spring 관리 빈에 위임 이며, 그것은 당신의 봄 응용 프로그램에서 빈 ("대상 콩 "또는"대리인 ")을 찾습니다" 컨텍스트를 호출하고 호출합니다. 그게 어떻게 가능해? 이 Bean은 javax.servlet.Filter를 구현하므로 doFilter 메소드가 호출됩니다.

어떤 콩이 호출됩니까? DelegatingFilterProxy "스프링 애플리케이션 컨텍스트에서 대상 빈의 이름을 지정하는"targetBeanName "[...]을 지원합니다."

web.xml에서 보았 듯이 빈의 이름은 " springSecurityFilterChain " 입니다.

따라서 웹 애플리케이션의 컨텍스트에서 필터는 애플리케이션 컨텍스트에서 "springSecurityFilterChain"이라는 빈을 인스턴스화 한 다음 doFilter () 메소드를 통해 위임합니다.

애플리케이션 컨텍스트는 모든 APPLICATION-CONTEXT (XML) 파일로 정의됩니다. 예를 들어 : applicationContext.xml 및 applicationContext-security.xml.

따라서 후자에서 "springSecurityFilterChain"이라는 빈찾으십시오 .

... 그리고 아마 그렇게 할 수 없습니다 (예를 들어 튜토리얼을 따랐거나 Roo를 사용하여 보안을 구성한 경우).

여기에 마술은 다음과 같습니다 새로운 요소가 보안을 구성하는 데있어 , 같은 뭔가를

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

http://www.springframework.org/schema/security/spring-security-3.0.xsd 에서 허용 하므로 트릭을 수행합니다.

Spring이 XML 파일을 사용하여 애플리케이션 컨텍스트를로드 할 때 요소를 찾으면 HTTP 보안, 즉 필터 스택 및 보호 된 URL을 설정하고 "springSecurityFilterChain"이라는 FilterChainProxy를 등록하려고 시도합니다.

또는 다음과 같은 고전적인 방식으로 Bean을 정의 할 수 있습니다.

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

그러나 많은 구성을 수행해야하므로 권장하지 않습니다 (사용할 모든 필터. 그리고 12 개 이상).


"applicationContext-security.xml AND applicationContext-security.xml"은 동일한 파일 이름이 두 번입니다.
musiKk 2014 년

감사합니다 musiKk은 (난 당신이 직접 후 편집 할 수 있습니다 생각)
jbbarquero

이것은 내가 모든 것을 찾고 있었고 나를 위해 일을 정리했다는 설명이었습니다.
user871611

@jbbarquero : 당신 말이 맞지만 올바른 버전이 뭔지 잘 모르겠습니다. 나는 의도하지 않게 의미를 바꾸지 않도록 원저자가 수정하도록 남겨 두는 경향이 있습니다.
musiKk 2014

확인. 어쨌든 내 답변을 개선하는 데 도움을 주셔서 감사합니다. 다시 한 번 감사드립니다, musiKk
jbbarquero

73

서블릿 필터 가 무엇 이며 어떻게 작동하는지 알고 있습니까? Servlet Spec의 매우 유용한 부분으로 HTTP 요청 서비스에 AOP와 유사한 개념을 적용 할 수 있습니다. 많은 프레임 워크는 다양한 용도로 필터 구현을 사용하며 작성하기가 매우 간단하고 유용하기 때문에 맞춤 구현을 찾는 것이 드문 일이 아닙니다. Spring 앱에서 앱이 할 수있는 대부분의 작업은 Spring Bean에 있습니다. 하지만 필터 인스턴스는 Servlet 컨테이너에 의해 제어됩니다. 컨테이너는 인스턴스화, 초기화 및 삭제합니다. Servlet Spec은 어떤 종류의 Spring 통합도 필요로하지 않으므로 Spring 앱과 작업을 수행하는 Bean에 연결하는 편리한 방법이없는 정말 유용한 개념 (필터) 만 남았습니다.

DelegatingFilterProxy를 입력합니다. Filter 구현을 작성하고 Spring Bean으로 만들지 만 web.xml에 고유 한 Filter 클래스를 추가하는 대신 DelegatingFilterProxy를 사용하고 Spring 컨텍스트에서 필터의 Bean 이름을 제공합니다. (명시 적으로 이름을 제공하지 않으면 "filter-name"을 사용합니다.) 그런 다음 런타임에 DelegatingFilterProxy는 Spring에서 작성하고 구성한 실제 구현을 찾고 요청을 라우팅하는 복잡성을 처리합니다. . 따라서 런타임에 필터를 web.xml에 나열한 것처럼 보이지만 다른 Spring Bean처럼 연결할 수 있다는 이점이 있습니다.

web.xml에서 해당 필터 매핑을 가져 오면 모든 것이 계속 작동하지만 어떤 URL도 보안되지 않습니다. (이것은 "springSecurityFilterChain"이라는 이름이 그것이하는 일을 정확하게 설명한다고 가정합니다.) 이는이 매핑이 들어오는 모든 요청을 필터링하고이를 Spring 컨텍스트에 정의 된 보안 필터로 전달하기 때문입니다.


이 빛나는 댓글을 게시 해 주셔서 감사합니다. 나는 지금 Spring Security를 ​​배우고 있으며 사용자 정의를 수행하기에 충분히 이해하려고 노력하고 있습니다. 서블릿 필터가 무엇인지 또는 스프링 필터가 무엇인지 전혀 몰랐습니다. AOP에 대한 귀하의 의견은 서블릿을 사용하는 대신 필터를 사용하는 이유를 명확하게 보여줍니다 ........ 따라서 각 서블릿 / 리소스에서 동일한 사전 / 사후 처리를 반복해서 작성할 필요가 없습니다.
Steve

와. 그 설명이 정확히 내가 필요했던 것입니다. 지식을 공유해 주셔서 감사합니다.
Charles Morin 2014

@Ryan Stewart 두 개의 bean이 applicationContext에서 Filter 인터페이스를 구현하고 순서대로 실행하려면 어떻게 만들 수 있습니까?
Abhishek Nayak 2014

@skaffman 두 개의 bean이 applicationContext에서 Filter 인터페이스를 구현하고 순서대로 실행하려면 어떻게 만들 수 있습니까?
Abhishek Nayak 2014

44

서블릿 필터 란 무엇입니까?

서블릿 필터 는 일반적으로 Java WebApp 개념입니다. 애플리케이션에서 Spring 프레임 워크를 사용하는지 여부에 관계없이 모든 웹 애플리케이션에서 서블릿 필터를 가질 수 있습니다.

이러한 필터는 대상 서블릿에 도달하기 전에 요청을 가로 챌 수 있습니다. 서블릿 필터에서 권한 부여와 같은 공통 기능을 구현할 수 있습니다. 일단 구현되면 web.xml에서 필터를 구성하여 특정 서블릿, 특정 요청 URL 패턴 또는 모든 URL 패턴에 적용 할 수 있습니다.

서블릿 필터는 어디에 사용됩니까?

최신 웹 앱에는 이러한 필터가 수십 개있을 수 있습니다. 권한 부여, 캐싱, ORM 세션 관리 및 종속성 주입과 같은 것들은 종종 서블릿 필터의 도움으로 구현됩니다. 이러한 모든 필터는에 등록해야합니다 web.xml.

서블릿 필터 인스턴스화-Spring Framework없이

서블릿 컨테이너는에서 선언 된 필터의 인스턴스를 생성 web.xml하고 적절한 시간에 호출합니다 (예 : 서블릿 요청을 처리 할 때). 이제 대부분의 DI (Dependency Injection) 팬이라면 인스턴스 생성이 내 DI 프레임 워크 (Spring)가 더 잘하는 것이라고 말할 수 있습니다. Spring으로 만든 서블릿 필터를 얻을 수 없어 모든 DI의 장점을 충족시킬 수 있습니까?

DelegatingFilterProxy, Spring이 필터 인스턴스를 생성하도록

여기서 DelegatingFilterProxy단계는 Spring Framework에서 제공 DelegatingFilterProxy하는 javax.servlet.Filter인터페이스 의 구현입니다 . DelegatingFilterProxyweb.xml에서 구성하면 스프링 구성에서 필터링을 수행하는 실제 을 선언 할 수 있습니다. 이런 식으로 Spring은 실제 필터링을 수행하는 Bean의 인스턴스를 생성하고 DI를 사용하여 이러한 Bean을 구성 할 수 있습니다.

에서 단일 DelegatingFilterProxy선언 만 필요 web.xml하지만 bean애플리케이션 컨텍스트에서 여러 필터링을 함께 연결할 수 있습니다 .


아주 잘 설명되었습니다.
user4906240

15

문제는 서블릿 필터가 스프링이 아닌 서블릿 컨테이너에 의해 관리된다는 것입니다. 그리고 일부 스프링 부품을 필터에 주입해야 할 수도 있습니다.

따라서 다음과 같은 것이 필요한 경우 :

public class FooFilter {

    @Inject
    private FooService service;

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

}

그런 다음 위임 필터 프록시가 필요합니다.


1

당신은 '접착제'에 대해 맞습니다. FilterChainProxy의 JavaDocs에 작성된대로 :

FilterChainProxy는 애플리케이션 web.xml 파일에 표준 Spring DelegatingFilterProxy 선언을 추가하여 서블릿 컨테이너 필터 체인에 연결됩니다.

훌륭한 설명을 보려면 Behind the Spring Security Namespace 블로그의 FIlterChainProxy 섹션을 참조하십시오 .


0

web.xml의 "springSecurityFilterChain"에 당혹 스러웠고 springframework 보안 문서에서이 답변을 찾았습니다.

<http>요소는 애플리케이션의 웹 계층에 대한 보안 구성을 캡슐화합니다. > 웹 보안 구성을 구성하는 보안 필터 스택을 유지하는 "springSecurityFilterChain"이라는 FilterChainProxy 빈을 생성합니다 [19]. 일부 핵심 필터는 항상> 생성되고 나머지는> 존재하는 속성 하위 요소에 따라 스택에 추가됩니다. 표준 필터의 위치는 고정되어 (> 네임 스페이스 소개의 필터 순서 표 참조), 사용자가 FilterChainProxy 빈에서 필터 체인을 명시 적으로 구성해야 할 때 이전 버전의 프레임 워크에서 발생하는 일반적인 오류 원인을 제거합니다. > 과정에서 구성을 완전히 제어해야하는 경우에도이 작업을 수행 할 수 있습니다.

다음은 http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-namespace.html 링크입니다.


0

오랜 시간 이었지만 같은 질문이 있었고 이것을 발견했습니다. https://www.javacodegeeks.com/2013/11/spring-security-behind-the-scenes.html

문제의 필터를 제거하고 추가하여 봄 보안 프로젝트를 실행하려고했습니다. 내가 찾은 것은 필터를 추가하면 호출이 스프링 보안 구성에 정의 된 필수 로그인 페이지로 리디렉션된다는 것입니다.

따라서 @Ryan의 답변에 동의합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.