- Filter
当一个请求到来时,在安全处理上最高层的元件,像是会话处理、验证、登出等,并呼叫对应的物件进行处理。
- Manager
真正处理验证、登出等安全服务之元件,Manager管理Provider所提供的安全相关资讯。
- Provider
提供安全相关资讯给Manager,安全资讯来源可能是记忆体中的物件、档案、资料库等储存媒介,安全资讯包括了使用者名称、密码、角色等讯息。
- Handler
有时会将一个安全服务分作数个小任务来进行,每个小任务由一个Handler来进行处理,如此在处理安全服务或设定Acegi时可以更有弹性,例如依需求处理登出时Session的失效与Cookie的失效。
Acegi使用Filter来对请求进行验证与授权等安全服务:
<!-- Filter Chain -->
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,
exceptionTranslationFilter,filterSecurityInterceptor
</value>
</property>
</bean>
以下介绍主要的几个Filter:
- Session Integration Filter
通常是Filter Chain中第一个Filter,会建立Security Context 物件用以储存安全相关资讯,后续的Filter若有需要储存或取得安全相关资讯,即可利用Security Context 物件,如果Security Context物件中的资讯有所变动,Session Integration Filter会将变动储存至Session物件之中,否则将Security Context物件弃置,例如“第一个Acegi程式”中所使用的Authentication Processing Filter,即利用Security Context物件来储存使用者名称、密码等使用者资讯。
- Authentication Processing Filter
当使用者存取受保护资源而需要登入时,Authentication Processing Filter可提供表单来源给使用者,之后从使用者的请求(物件)中取得名称、密码并建立authentication token以储存资讯,接着将之交给验证管理员(authentication manager)进行以进行使用者的比对,所以基本上,Authentication Processing Filter需要设定以下的资讯:
<!-- 验证处理,使用表单 -->
<bean id="authenticationProcessingFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<!-- 验证管理员,处理验证资讯提供者 -->
<property name="authenticationManager" ref="authenticationManager"/>
<!-- 验证失败URL -->
<property name="authenticationFailureUrl" value="/acegilogin.jsp"/>
<!-- 验证成功预设URL -->
<property name="defaultTargetUrl" value="/protected/userinfo.jsp"/>
<!-- 验证处理的提交位址 -->
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
</bean>
<bean id="authenticationProcessingFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<!-- 验证管理员,处理验证资讯提供者 -->
<property name="authenticationManager" ref="authenticationManager"/>
<!-- 验证失败URL -->
<property name="authenticationFailureUrl" value="/acegilogin.jsp"/>
<!-- 验证成功预设URL -->
<property name="defaultTargetUrl" value="/protected/userinfo.jsp"/>
<!-- 验证处理的提交位址 -->
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
</bean>
当验证管理员进行使用者的比对、取得细节资讯并返回Authentication Processing Filter后,Authentication Processing Filter会建立Authentication并将取得的使用者资讯储存在Security Context物件中,然后交给下一个Filter继续进行处理。
- Exception Translation Filter
当验证或授权过程中发生例外时,Exception Translation Filter处理例外。
<!-- 发生验证错误或权限错误时的处理 -->
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/acegilogin.jsp"/>
<property name="forceHttps" value="false"/>
</bean>
</property>
<property name="accessDeniedHandler">
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.jsp"/>
</bean>
</property>
</bean>
<!-- 发生验证错误或权限错误时的处理 -->
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/acegilogin.jsp"/>
<property name="forceHttps" value="false"/>
</bean>
</property>
<property name="accessDeniedHandler">
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.jsp"/>
</bean>
</property>
</bean>
- Logout Processing Filter
管理登出的处理,实际的登出处理会交给Handler,您可以设置登出后的显示页面来源,在 第一个Acegi 程式 - 登出、自动Cookies登入 中,使用了SecurityContextLogoutHandler来让Session交效。
<!-- 登出处理 --> <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/acegilogin.jsp"/> <!-- 登出后的显示页面 -->
<constructor-arg>
<list>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
<constructor-arg value="/acegilogin.jsp"/> <!-- 登出后的显示页面 -->
<constructor-arg>
<list>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
- Interceptor filters
用来决定是否授权,验证与授权是一体的,所以在Authentication Processing Filter之后必须设定Interceptor filters,Interceptor filters使用您所设定的存取控制策略(access control policy)来决定是否授权,一个使用者的存取控制策略定义了使用者、密码、角色等资讯:
caterpillar=123456,ROLE_SUPERVISOR
caterpillar=123456,ROLE_SUPERVISOR
您使用Interceptor filters来进行存取控制策略的设定,设定验证管理者与存取决策理员(Access Decision Manager),受保护的资源可存取之角色,存取决策管理员会以投票方式决定资源是否授权,例如:
<!-- FilterSecurityInterceptor 对 URI 进行保护 --><bean id="filterSecurityInterceptor"
class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<!-- 验证管理员 -->
<property name="authenticationManager" ref="authenticationManager" />
<!-- 授权管理员 -->
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/protected/**=ROLE_SUPERVISOR,ROLE_USER
</value>
</property>
</bean>

