FilterInvocation을 보호하기 위해 개발자들은
FilterSecurityInterceptor에 위임하는 필터를
web.xml에 추가할 필요가 있다.
일반적인 설정 예제는 아래와 같이 제공된다:
<filter>
<filter-name>Acegi HTTP Request Security Filter</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.intercept.web.FilterSecurityInterceptor</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Acegi HTTP Request Security Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>필터가 실제로는 FilterToBeanProxy라는 점을 명심하도록 한다.
Acegi Security에서 사용되는 필터들은 대부분 이 클래스를 사용한다.
이 빈에 대해 좀 더 알아보려면 "필터" 섹션을 참조하도록 한다.
애플리케이션 컨텍스트에는 세 개의 빈을 설정해야 할 것이다:
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint"><ref local="authenticationEntryPoint"/></property>
</bean>
<bean id="authenticationEntryPoint" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
<property name="forceHttps"><value>false</value></property>
</bean>
<bean id="filterSecurityInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/secure/super/.*\Z=ROLE_WE_DONT_HAVE
\A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
</value>
</property>
</bean> ExceptionTranslationFilter는 Java 예외와
HTTP 응답을 이어준다. ExceptionTranslationFilter는
단독적으로 사용자 인터페이스를 유지하는 것에만 관심을 갖고 있다.
이 필터는 어떠한 실질적인 보안 강화책을 수행하지는 않는다.
만약 AuthenticationException이 감지되면
필터는 AuthenticationEntryPoint를 호출하여
인증 절차를 시작할 것이다(예, 사용자 로그인).
AuthenticationEntryPoint는 사용자가 안전한 HTTP 리소스를
요청했지만 인증되지 않았을 경우 호출될 것이다. 이 클래스는 사용자에게
적절한 응답을 나타내는 것을 처리하여 인증이 시작될 수 있도록 한다. Acegi Security에는
세 개의 구상 구현체가 제공된다. AuthenticationProcessingFilterEntryPoint는
폼 기반의 인증을 시작하는데 사용되고, BasicProcessingFilterEntryPoint는
HTTP Basic 인증 프로세스를 시작하는데 사용되며, 그리고 CasProcessingFilterEntryPoint는
JA-SIG 중앙 인증 서비스(JA-SIG CAS; JA-SIG Central Authentication Service)
로그인을 시작하는데 사용된다. AuthenticationProcessingFilterEntryPoint와
CasProcessingFilterEntryPoint는 HTTPS를 사용하도록 하는 것과 관련되어 있는 선택적인
프로퍼티를 갖고 있으며, 필요하면 JavaDoc을 참조하도록 한다.
FilterSecurityInterceptor는 HTTP 자원의 보안을
처리할 책임이 있다. 다른 보안 인터셉터와 유사하게
FilterSecurityInterceptor는
AuthenticationManager와 AccessDecisionManager에
대한 참조를 필요로 하며, 둘 모두 아래의 별도 섹션에서 논의할 것이다.
또한 FilterSecurityInterceptor는 서로 다른 HTTP URL 요청에
적용되는 설정 속성도 설정한다.
FilterSecurityInterceptor에는 두 가지 방법으로
설정 속성들이 설정될 수 있다. 첫 번째 방법은 프로퍼티 에디터와
애플리케이션 컨텍스트를 통한 것이며, 위에서 보여지는 것과 같다.
두 번째 방법은 비록 본 문서의 범위를 벗어나긴 하지만
여러분의 자체적인 ObjectDefinitionSource를 작성하는 것이다.
사용된 접근법과는 관계없이 ObjectDefinitionSource는 하나의 안전한
HTTP URL과 연결되어 있는 설정 속성들을 모두 포함하는
ConfigAttributeDefinition 객체를 반환할 책임을 가진다.
주의할 점은
FilterSecurityInterceptor.setObjectDefinitionSource()
메소드가 실제로는 FilterInvocationDefinitionSource의
인스턴스를 기대한다는 것이다. FilterInvocationDefinitionSource는
마커 인터페이스며 ObjectDefinitionSource를 서브 클래싱하고 있다.
이 클래스는 단순히 ObjectDefinitionSource가
FilterInvocation를 알고 있다는 것만을 나타낸다.
단순함에 중점을 두어 우리는 계속해서
FilterInvocationDefinitionSource를
ObjectDefinitionSource로 언급할 것이며,
FilterSecurityInterceptor를 사용하는 사용자들에게는
그 둘을 구분하는 것이 크게 의미는 없을 것이다.
만약 애플리케이션 컨텍스트 프로퍼티 에디터 접근법을 사용할
경우(위에서 보이는 것과 같이), 콤마(,)를 사용하여 각각의 HTTP URL에 해당되는
여러 설정 속성들을 분리한다. 각 설정 속성들은 자기 자신의
SecurityConfig 객체에 할당된다.
SecurityConfig 객체는 고수준 설계(High Level Design) 섹션에서
논의할 것이다. ObjectDefinitionSource는
프로퍼티 에디터인 FilterInvocationDefinitionSource에 의해 생성되며,
요청 URL의 표현 평가에 근거하여 FilterInvocations과 설정 속성들을
일치시키며, 두 표준 표현식 문법을 모두 지원한다. 기본값은 모든 표현식을 정규 표현식으로 다루는 것이다.
대안으로 PATTERN_TYPE_APACHE_ANT 지시자가 있으면 모든 표현식을
Apache Ant 패스로 다룰 것이다. 동일한 정의 내에서는 표현식 문법들을
섞어 사용할 수 없다. 예를 들면 다음과 같이 Apache Ant 패스를 이용해서는
앞서 보았던 설정을 만들어낼 수 없다.
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/secure/super/**=ROLE_WE_DONT_HAVE
/secure/**=ROLE_SUPERVISOR,ROLE_TELLER
</value>
</property>
</bean> 어떠한 유형의 문법을 사용하는지와는 상관없이 표현식은 항상 정의되어 있는
순서대로 평가된다. 중요한 것은 좀 더 구체적인 표현식들이 보다 덜 구체적인
표현식보다 위에 정의된다는 점이다. 이는 위의 예제의 경우 좀 더 구체적인
/secure/super/ 패턴이 보다 덜 구체적인 /secure/
패턴보다 윗부분에 나타난다는 것을 보여준다. 만약 순서를 뒤바꾸게 되면
/secure/ 패턴이 항상 일치하게 되므로
/secure/super/ 패턴은 절대로 평가되지 않을 것이다.
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON이라는
이름의 특수한 키워드는 FilterInvocationDefinitionSource가
자동적으로 표현식으로 비교되기 전에 요청 URL을 소문자로 변환하도록 해준다.
기본적으로 요청 URL이 변환되지 않는 경우라도, 일반적으로
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON을 사용하여
각 표현들이 소문자로 작성되어 있다고 가정하도록 할 것을 권장한다.
다른 보안 인터셉터와 같이 validateConfigAttributes
프로퍼티는 관찰된다. 설정값을 true로 지정할 경우(기본값),
시작시 FilterSecurityInterceptor가 제공된
설정 속성들의 유효성 여부가 평가될 것이다. 이는 각 설정 속성들이
AccessDecisionManager나 RunAsManager에 의해
처리될 수 있는지를 확인함으로써 이루어진다. 이것들 중 주어진
설정 속성들을 처리할 수 있는 것이 아무것도 없다면 예외가 던져질 것이다.