3. 其它組件
AccessDecisionManager
AccessDecisionManager接口有decide()和support()方法。decide()方法是進行決策是否批准通過,如果沒拋出AccessDeniedException則爲允許訪問資源,否則拒絕訪問。support()方法是根據配置屬性和受保護資源的類來判斷是否需要對該資源作出決策判斷。
AccessDecisionManager的 decisionVoters屬性需要一個或多個Voter(投票者),Voter必須實現AccessDecisionVoter 接口。Voter的工作是去匹配用戶已擁有的權限和受保護的資源要求的權限,在該資源有相應權限的情況下,如果匹配則投允許票,否則投反對票。 allowIfAllAbstainDecisions屬性表示是否允許所有都棄權時就通過。Voter的實現類RoleVoter在當受保護資源的名字由ROLE_開始時才參與投票。
AccessDecisionManager有三個實現類,功能各不相同:
AffirmativeBased: 當至少有一個Voter投允許票時才通過
UnanimousBased: 沒有Voter投反對票時才通過
ConsensusBased: 當所有Voter都投允許票時才通過
<bean id="accessDecisionManager" class="org.acegisecurity.vote.UnanimousBased">
<property name="allowIfAllAbstainDecisions">
<value>false</value>
</property>
<property name="decisionVoters">
<list>
<ref local="roleVoter" />
</list>
</property>
</bean>
<bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter" />
AuthenticationManager
AuthenticationManager的其中一個實現是ProviderManager,它負責把身份驗證的工作委託給一個或多個Provider(認證提供者)。
Provider都是實現AuthenticationProvider接口,該接口有兩個方法authenticate()和support ()。authenticate()方法會嘗試驗證用戶身份,若驗證成功則返回一個Authentication對象,否則拋出一個 AuthenticationException。
support()方法會評估當前Authentication對象是否適合這Provider來進行進一步的處理,而不是指已經通過。
Provir有多個實現,例如daoAuthenticationProvider,anonymousAuthenticationProvider,rememberMeAuthenticationProvider。
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
<ref local="anonymousAuthenticationProvider"/>
<ref local="rememberMeAuthenticationProvider"/>
</list>
</property>
</bean>
daoAuthenticationProvider負責提供用戶信息,包括用戶名和密碼。其中取用戶名密碼的工作就交給 userDetailsService來做。通過userCache來緩存用戶信息,減少查詢數據庫次數。用passwordEncoder來使用加密密碼。userDetailsService的接口實現有jdbcDaoImpl和inMemoryDaoImpl。jdbcDaoImpl通過數據庫獲取用戶名和密碼,而inMemoryDaoImpl則只是通過xml定義的方式來獲取。
userCache的接口實現有EhCacheBasedUserCache和NullUserCache。NullUserCache實際上就是不進行緩存。EhCacheBasedUserCache是基於ehcache的開源緩存項目來實現的。
passwordEncoder是使用加密器對用戶輸入的明文進行加密。Acegi提供了三種加密器:
PlaintextPasswordEncoder---默認,不加密,返回明文.
ShaPasswordEncoder---哈希算法(SHA)加密
d5PasswordEncoder---消息摘要(MD5)加密
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
<property name="userCache"><ref local="userCache"/></property>
<property name="passwordEncoder"><ref local="passwordEncoder"/></property>
</bean>
<bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>
<bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache"><ref local="userCacheBackend"/></property>
</bean>
<bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.Md5PasswordEncoder"/>
<bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<ref local="cacheManager"/>
</property>
<property name="cacheName">
<value>userCache</value>
</property>
</bean>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
anonymousAuthenticationProvider負責匿名用戶的AnonymousAuthenticationToken的進一步處理
<bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key"><value>foobar</value></property>
</bean>
rememberMeAuthenticationProvider負責Cookies記憶用戶RememberMeAuthenticationToken的進一步處理
<bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key"><value>springRocks</value></property>
</bean>
RememberMeServices
rememberMeServices負責通過以cookie的形式保存先前的用戶登錄信息。在Authentication對象不存在時, rememberMeProcessingFilter會調用rememberMeServices的autoLogin()方法,嘗試在cookie中獲取用戶登錄信息,如果存在則並返回Authentication對象。在每次用戶登錄時,如果設置了RememberMe功能,在驗證用戶身份成功後,則會調用loginSuccess()方法記錄用戶信息在cookie中,否則調用loginFail()方法清除cookie。
<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="userDetailsService" />
<property name="key" value="changeThis" />
</bean>
runAsManager
runAsManager提供了動態替換 ContextHolder中Authentication對象的功能。
<bean id="runAsManager" class="org.acegisecurity.runas.RunAsManagerImpl">
<property name="key">
<value>my_run_as_password</value>
</property>
</bean>