当用户认证成功之后,默认cas服务器只返回用户名给客户端。那么客户端能否从cas服务器获取更多的信息吗?答案是肯定的。cas需要返回更多的信息时,就需要用到person directory。在用户认证成功之后,cas服务器有一步是将credentials向Principal转化的过程,这个工作是由credentialsToPrincipalResolvers完成,参见cas 入门之四:认证管理器。
cas 应用的默认配配置是:
<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>
其中attributeRepository就是我们需要重点去理解的,这个是就是向客户端返回更多信息的接口或者说是通过外部系统向cas服务器提供更多用户信息的接口。cas 服务器通过这个接口获取更多的认证成功的用户信息,然后返回给客户端。这个接口就是person direcotry项目,它同样也是jasig公司开发的一个项目,但是目前好像不提供源码下载。对于各种业务场景下的用户信息提供,都可以通过它来完成。因为从上面spring bean的配置方式,我们也可以猜测的到credentialsToPrincipalResolvers在转换的过程中,只需要从attributeRepository这里获取用户的相应信息,而不需要进行用户信息的相应处理,如果不是这样那么就没有必要专门开发这样一个项目。比如从数据库中获取用户信息,都有现成的解决方案。
person directory 只有两个接口:
1.获取用户属性方式接口
org.jasig.services.persondir.IPersonAttributeDao
2.被获取的用户属性对象
org.jasig.services.persondir.IPersonAttributes
person directory 主要围绕这两个接口实现多种用户属性获取方式及获取的用户属性对象。下面主要列举一些比较常用的属性获取方式。
通过jdbc向关系数据库中获取用户信息
a.当用户信息,是按行存储,则用org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao
比如数据表结构:
create user_data{ user_name varchar2(50), dept_id number(10), first_name varchar2(50), email varchar2(50) }
SingleRowJdbcPersonAttributeDao的配置如下:
<bean id="singleRowJdbcPersonAttributeDao" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"> <constructor-arg index="0" ref="dataSource" /> <constructor-arg index="1" value="SELECT * FROM user_data WHERE {0}" /> <property name="queryAttributeMapping"> <map> <entry key="username" value="user_name" /> <!--这个用于查询条件中,key是用户名,user_name对应用户表user_data中的相应用户名字段 --> </map> </property> <property name="resultAttributeMapping"> <map> <!-- 这个map key对应用户数据表user_data中的字段,而value对应客户端获取相应值的约定属性名 --> <entry key="user_name" value="username" /> <entry key="first_name" value="firstName" /> <entry key="dept_id" value="deptId" /> <entry key="email" value="email" /> </map> </property> </bean>
b.当用户信息,是按列存储,则用org.jasig.services.persondir.support.jdbc.MultiRowJdbcPersonAttributeDao
比如表结构:
create table user_data{ user_name varchar2(50), attr_name varchar2(50), attr_value varchar2(50) }; insert into user_data(user_name,attr_name,attr_value) into('test','first_name','alibaba'); insert into user_data(user_name,attr_name,attr_value) into('test','email','test@example.com');
配置:
<bean id="multiRowJdbcPersonAttributeDao" class="org.jasig.services.persondir.support.jdbc.MultiRowJdbcPersonAttributeDao"> <constructor-arg index="0" ref="dataSource" /> <constructor-arg index="1" value="SELECT * FROM USER_DATA WHERE {0}" /> <property name="queryAttributeMapping"> <map> <entry key="username" value="user_name" /> </map> </property> <property name="nameValueColumnMappings"> <map> <entry key="attr_name" value="attr_value" /> </map> </property> <property name="resultAttributeMapping"> <map> <entry key="user_name" value="username" /> <entry key="first_name" value="firstName" /> <entry key="email" value="email" /> </map> </property> </bean>
其中dataSource自行配置
它的配置:
<bean id="ldapPersonAttributeDao" class="org.jasig.services.persondir.support.ldap.LdapPersonAttributeDao"> <property name="contextSource" ref="contextSource" /> <property name="baseDN" value="o=example.com,o=isp" /> <property name="queryAttributeMapping"> <map> <entry key="username" value="user_name" /> </map> </property> <property name="resultAttributeMapping"> <map> <entry key="user_name" value="username" /> <entry key="first_name" value="firstName" /> <entry key="mail" value="email" /> </map> </property> </bean>
其中contextSource 自行配置。
发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)