一、概括
在大多数情况下,随着用户登录系统后,用户 ID、用户名、E-mail、用户头像等等基本信息,需要被使用直到用户退出系统。
CAS Server 默认情况下,成功登录后,只会返回用户标示(通常是用户名)给 CAS Client。这时,各个 Client 还需要根据用户标示,去查询用户其它信息,这时如果如果 CAS Server 统一将这些信息返回给 Client 了,各个 Client 就无需再次进行查询了。
二、配置
修改 deployerConfigContext.xml
-
修改
1<bean id="attributeRepositoryDao" class="com.buession.cas.service.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"> 2 <property name="jdbcTemplate" ref="slaveJdbcTemplate" /> 3 <property name="queryTemplate" value="SELECT * FROM `member` WHERE {0} LIMIT 1" /> 4 <property name="queryAttributeMapping"> 5 <map> 6 <entry key="username" value="username" /> 7 </map> 8 </property> 9 <property name="resultAttributeMapping"> 10 <map> 11 <!-- key 对应数据库字段名,value 为查询结果转换为 Map 的 key --> 12 <entry key="id" value="id" /> 13 <entry key="username" value="username" /> 14 <entry key="email" value="email" /> 15 ... ... 16 </map> 17 </property> 18</bean>SQL 语句最终会转换为: SELECT * FROM `member` WHERE username(queryAttributeMapping Map Entry 中的 value) = '登录表单中的 username' LIMIT 1
-
修改
1<bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl"> 2 <property name="registeredServices"> 3 <list> 4 <bean class="org.jasig.cas.services.RegexRegisteredService"> 5 ... ... 6 <property name="ignoreAttributes" value="true" /> 7 <!-- 或者 --> 8 <property name="allowedAttributes"> 9 <list> 10 <!-- 11 value 的值对应 attributeRepositoryDao resultAttributeMapping 的 entry 的 value 属性 12 只有这里定义了元素,才会真正从 resultAttributeMapping 返回给 client 13 --> 14 <value>id</value> 15 <value>username</value> 16 <value>email</value> 17 ... ... 18 </list> 19 </property> 20 </bean> 21 ... ... 22 </list> 23 </property> 24</bean>当 ignoreAttributes 为 true 时,则返回获取到的全部用户信息给 CAS Client,而不根据 “allowedAttributes” 对结果进行过滤
-
假设是多条件登录,则需要修改
1<bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl"> 2 ... ... 3 <property name="authenticationHandlers"> 4 <list> 5 <bean class="com.domain.authentication.handler.DatabaseAuthenticationHandler"> 6 <property name="jdbcTemplate" ref="slaveJdbcTemplate" /> 7 <property name="sql" value="SELECT `username`, ...... FROM `member` WHERE `username` = ? OR `email` = ? OR `mobile` = ?" /> 8 <property name="passwordEncoder" ref="passwordEncoder" /> 9 </bean> 10 </list> 11 </property> 12</bean> 13 14class DatabaseAuthenticationHandler extends com.buession.cas.authentication.handler.support.DatabaseQueryAuthenticationHandler { 15 16 @Override 17 protected boolean authenticateUsernamePasswordInternal(UsernamePasswordCredentials credentials) 18 throws AuthenticationException { 19 ... ... 20 try { 21 ... ... 22 if (valid(username, password, r, passwordEncoder) == true) { 23 credentials.setUsername((String) r.get("username")); 24 return ture; 25 } 26 } catch (IncorrectResultSizeDataAccessException e) { 27 } 28 29 return false; 30 } 31 32}登录验证 SQL 语句中,你必需得返回与 queryAttributeMapping Map 中 value 一致的字段,然后在 DatabaseAuthenticationHandler.authenticateUsernamePasswordInternal 中验证成功后,重新赋值给 UsernamePasswordCredentials 的 username,以方便根据一个唯一的用户值去查询更多的用户信息。
-
在模板文件 WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp 中添加
1<c:if test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes) > 0}"> 2 <cas:attributes> 3 <c:forEach var="r" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}"> 4 <cas:${fn:escapeXml(r.key)}>${fn:escapeXml(r.value)}</cas:${fn:escapeXml(r.key)}> 5 </c:forEach> 6 </cas:attributes> 7</c:if>
三、结果

注意:cas:user 是登录表单中输入的 username,可能是用户名、e-mail、手机号码等等