之前我分析过cas的spring配置文件,其中有一个spring文件名为deployerConfigContext.xml,在这里面我们可以找到类似如下的spring bean配置(我去掉了相关的注释说明):
<bean id="authenticationManager"
class="org.jasig.cas.authentication.AuthenticationManagerImpl">
<property name="credentialsToPrincipalResolvers">
<list>
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" >
<property name="attributeRepository" ref="attributeRepository" />
</bean>
<bean
class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
</list>
</property>
<property name="authenticationHandlers">
<list>
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" p:requireSecure="false"/>
<bean
class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
</list>
</property>
</bean>
这个bean,就是cas的核心类,认证管理器。在cas中定义了两个术语credentials,即需认证用户信息载体,例如在web应用中,用户通过前台界面输入用户名,密码,然后经cas 认证成功(或失败)。这个credentials它的其中一个实现类(org.jasig.cas.authentication.principal.UsernamePasswordCredentials)
就代表了持有前台输入的用户名及密码类;另一个术语是Principal,它是cas认证之后返回的信息载体,默认只返回用户名。从上面的配置我们看到这个bean有两个属性:
authenticationHandlers从字面意思可知是认证处理器,即cas如何对于用户信息进行认证,即到哪去认证;credentialsToPrincipalResolvers对于认证之后的用户信息转换为principal的转换解析器。这两个属性都是list即可以配置多个。在cas的认证过程中逐个执行authenticationHandlers中配置的认证管理,直到有一个成功为止;然后再执行credentialsToPrincipalResolvers过程,直到有一个成功为止。这是cas认证管理器的默认配置.我们从上面的分析会发现,默认配置在进行认证及转换解析是低效的,原因是它要执行两次for循环(当然这个低效也是相对的),那么是否可以提高相应的效率呢?答案是肯定的。
cas的认证管理器有三个实现类:
org.jasig.cas.authentication.AuthenticationManagerImpl;
org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl;
org.jasig.cas.authentication.LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager
第一个就是默认配置。认证管理器的第二及第三类实现,就来解决这件事情。
我们先来说说LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager这个类。DirectMappingAuthenticationManagerImpl这个不太好说。
LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager从类名我们可以猜出它是将认证处理器与转换解析器进行对应。实质上它就是作这件事情的,即
将一个authenticationHander指定一个credentialToprincipalResolver.它的一般配置与如下类似:
<bean id="authenticationManager"
class="org.jasig.cas.authentication.LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager">
<constructor-arg name="linkedHandlers"
ref="authenticationHandlersAndPrincipalResolversMap" />
</bean>
<util:map id="authenticationHandlersAndPrincipalResolversMap">
<entry key-ref="httpBasedAuthenticationHandler">
<bean
class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
</entry>
<entry key-ref="ldapBindAuthenticationHandler">
<bean
class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository" />
</bean>
</entry>
<entry key-ref="ldapFastBindAuthenticationHandler">
<bean
class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository" />
</bean>
</entry>
</util:map>
下面我们来说说
org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl,它不像上面那个类名那么明显就能猜出它的作用。它有一个
private Map<Class< ? extends Credentials>, DirectAuthenticationHandlerMappingHolder> credentialsMapping属性,
即对于每一种credentials绑定一个DirectAuthenticationHandlerMappingHolder,而DirectAuthenticationHandlerMappingHolder实质就是持有一个认证处理器与一个pricipal转换解析器,这样就能将credentials,认证处理器与转换解析器进行了绑定,它的一般配置类似如下:
<bean id="authenticationManager"
class="org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl">
<property name="credentialsMapping">
<map>
<entry
key="org.jasig.cas.authentication.principal.UsernamePasswordCredentials">
<bean
class="org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl.DirectAuthenticationHandlerMappingHolder"
p:authenticationHandler-ref="ldapHandler"
p:credentialsToPrincipalResolver-ref="ldapResolver" />
</entry>
<entry
key="org.jasig.cas.adaptors.x509.authentication.principal.X509CertificateCredentials">
<bean
class="org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl.DirectAuthenticationHandlerMappingHolder"
p:authenticationHandler-ref="certHandler"
p:credentialsToPrincipalResolver-ref="certResolver" />
</entry>
</map>
</property>
</bean>
对于普通的不追求性能的系统来说,cas的默认认证管理器配置是最合适不过了,它非常的灵活,易于扩展,只需要追加认证管理器与principal转换解析器就可以了,而无需关心其他。而在我们追求性能,而且需要对于某一种credentials进行多次认证处理(例如对于用户名密码组合从多个数据源进行验证),我们可以应用LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager认证管理器;而对于不同credentials进行认证处理,我们可以应用DirectMappingAuthenticationManagerImpl认证管理器。这三个认证管理器各有利弊,我们根据不同情况可以灵活应用。
<bean id="authenticationManager"
class="org.jasig.cas.authentication.AuthenticationManagerImpl">
<property name="credentialsToPrincipalResolvers">
<list>
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" >
<property name="attributeRepository" ref="attributeRepository" />
</bean>
<bean
class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
</list>
</property>
<property name="authenticationHandlers">
<list>
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" p:requireSecure="false"/>
<bean
class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
</list>
</property>
</bean>
这个bean,就是cas的核心类,认证管理器。在cas中定义了两个术语credentials,即需认证用户信息载体,例如在web应用中,用户通过前台界面输入用户名,密码,然后经cas 认证成功(或失败)。这个credentials它的其中一个实现类(org.jasig.cas.authentication.principal.UsernamePasswordCredentials)
就代表了持有前台输入的用户名及密码类;另一个术语是Principal,它是cas认证之后返回的信息载体,默认只返回用户名。从上面的配置我们看到这个bean有两个属性:
authenticationHandlers从字面意思可知是认证处理器,即cas如何对于用户信息进行认证,即到哪去认证;credentialsToPrincipalResolvers对于认证之后的用户信息转换为principal的转换解析器。这两个属性都是list即可以配置多个。在cas的认证过程中逐个执行authenticationHandlers中配置的认证管理,直到有一个成功为止;然后再执行credentialsToPrincipalResolvers过程,直到有一个成功为止。这是cas认证管理器的默认配置.我们从上面的分析会发现,默认配置在进行认证及转换解析是低效的,原因是它要执行两次for循环(当然这个低效也是相对的),那么是否可以提高相应的效率呢?答案是肯定的。
cas的认证管理器有三个实现类:
org.jasig.cas.authentication.AuthenticationManagerImpl;
org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl;
org.jasig.cas.authentication.LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager
第一个就是默认配置。认证管理器的第二及第三类实现,就来解决这件事情。
我们先来说说LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager这个类。DirectMappingAuthenticationManagerImpl这个不太好说。
LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager从类名我们可以猜出它是将认证处理器与转换解析器进行对应。实质上它就是作这件事情的,即
将一个authenticationHander指定一个credentialToprincipalResolver.它的一般配置与如下类似:
<bean id="authenticationManager"
class="org.jasig.cas.authentication.LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager">
<constructor-arg name="linkedHandlers"
ref="authenticationHandlersAndPrincipalResolversMap" />
</bean>
<util:map id="authenticationHandlersAndPrincipalResolversMap">
<entry key-ref="httpBasedAuthenticationHandler">
<bean
class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
</entry>
<entry key-ref="ldapBindAuthenticationHandler">
<bean
class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository" />
</bean>
</entry>
<entry key-ref="ldapFastBindAuthenticationHandler">
<bean
class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository" />
</bean>
</entry>
</util:map>
下面我们来说说
org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl,它不像上面那个类名那么明显就能猜出它的作用。它有一个
private Map<Class< ? extends Credentials>, DirectAuthenticationHandlerMappingHolder> credentialsMapping属性,
即对于每一种credentials绑定一个DirectAuthenticationHandlerMappingHolder,而DirectAuthenticationHandlerMappingHolder实质就是持有一个认证处理器与一个pricipal转换解析器,这样就能将credentials,认证处理器与转换解析器进行了绑定,它的一般配置类似如下:
<bean id="authenticationManager"
class="org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl">
<property name="credentialsMapping">
<map>
<entry
key="org.jasig.cas.authentication.principal.UsernamePasswordCredentials">
<bean
class="org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl.DirectAuthenticationHandlerMappingHolder"
p:authenticationHandler-ref="ldapHandler"
p:credentialsToPrincipalResolver-ref="ldapResolver" />
</entry>
<entry
key="org.jasig.cas.adaptors.x509.authentication.principal.X509CertificateCredentials">
<bean
class="org.jasig.cas.authentication.DirectMappingAuthenticationManagerImpl.DirectAuthenticationHandlerMappingHolder"
p:authenticationHandler-ref="certHandler"
p:credentialsToPrincipalResolver-ref="certResolver" />
</entry>
</map>
</property>
</bean>
对于普通的不追求性能的系统来说,cas的默认认证管理器配置是最合适不过了,它非常的灵活,易于扩展,只需要追加认证管理器与principal转换解析器就可以了,而无需关心其他。而在我们追求性能,而且需要对于某一种credentials进行多次认证处理(例如对于用户名密码组合从多个数据源进行验证),我们可以应用LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager认证管理器;而对于不同credentials进行认证处理,我们可以应用DirectMappingAuthenticationManagerImpl认证管理器。这三个认证管理器各有利弊,我们根据不同情况可以灵活应用。