我们再使用CAS作为单点登录服务器时,在某些情况下希望从CAS Server端获取更多的用户信息,比如用户姓名、手机号、Email等,默认情况下Cas至返回用户的登录名

基于以上的Cas版本,开始让Cas返回更多的用户信息。
一、配置属性attributeRepository
<bean id="selfAttributeRepository"
class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<constructor-arg index="0" ref="dataSource" />
<constructor-arg index="1"
value="select email,name,login_name,password from isc_user where {0}" />
<!-- 组装sql用的查询条件属性 -->
<property name="queryAttributeMapping">
<map>
<!-- key必须是uername而且是小写否则会导致取不到用户的其它信息,value对应数据库用户名字段,系统会自己匹配 -->
<entry key="username" value="login_name" />
</map>
</property>
<property name="resultAttributeMapping">
<map>
<!-- key为对应的数据库字段名称,value为提供给客户端获取的属性名字,系统会自动填充值 -->
<entry key="login_name" value="username"></entry>
<entry key="email" value="email"></entry>
<entry key="name" value="name"></entry>
<entry key="password" value="password"></entry>
</map>
</property>
</bean>
二、配置用户认证凭据转化的解析器
在deployerConfigContext.xml中,找到credentialsToPrincipalResolvers,为UsernamePasswordCredentialsToPrincipalResolver注入attributeRepository
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" >
<property name="attributeRepository" ref="attributeRepository" />
</bean>
替换成
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" > <property name="attributeRepository" ref="selfAttributeRepository" /> </bean>
三、将添加的用户信息返回给客户端
找到WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp。此文件作用是在server验证成功后,这个页面负责生成与客户端交互的xml信息,在默认的casServiceValidationSuccess.jsp中,只
包括用户登录名,并不提供其他的属性信息,因此需要对页面进行扩展。
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user>
<c:if test="${not empty pgtIou}">
<cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket>
</c:if>
<c:if test="${fn:length(assertion.chainedAuthentications) > 1}">
<cas:proxies>
<c:forEach var="proxy" items="${assertion.chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications)-2}" step="1">
<cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy>
</c:forEach>
</cas:proxies>
</c:if>
</cas:authenticationSuccess>
</cas:serviceResponse>
扩展为如下
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user>
<c:if test="${not empty pgtIou}">
<cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket>
</c:if>
<c:if test="${fn:length(assertion.chainedAuthentications) > 1}">
<cas:proxies>
<c:forEach var="proxy" items="${assertion.chainedAuthentications}"
varStatus="loopStatus" begin="0"
end="${fn:length(assertion.chainedAuthentications)-2}" step="1">
<cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy>
</c:forEach>
</cas:proxies>
</c:if>
<!-- 在server验证成功后,这个页面负责生成与客户端交互的xml信息,在默认的casServiceValidationSuccess.jsp中,只包括用户名,并不提供其他的属性信息,因此需要对页面进行扩展 -->
<c:if
test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes) > 0}">
<cas:attributes>
<c:forEach var="attr"
items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">
<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>
</c:forEach>
</cas:attributes>
</c:if>
</cas:authenticationSuccess>
</cas:serviceResponse>
通过完成上面三个步骤的配置后,server端的工作就完成了,那么如何在客户端获取这些信息呢?
下面进行说明:
欢迎,<%=AssertionHolder.getAssertion().getPrincipal().getName() %><br/>
<%
AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
String loginName = principal.getName();
out.println("loginName:" + loginName);
Map<String, Object> attributes = principal.getAttributes();
out.println("<br>");
if (attributes != null)
{
out.println("username:" + attributes.get("username"));
out.println("<br>");
out.println("password:" + attributes.get("password"));
out.println("<br>");
out.println("email:" + attributes.get("email"));
out.println("<br>");
out.println("name:" + attributes.get("name"));
out.println("<br>");
}
out.println("------------------华丽的分割线---------------------");
out.println("<br>");
AttributePrincipal principal2 = AssertionHolder.getAssertion().getPrincipal();
String loginName2 = principal2.getName();
out.println("loginName:" + loginName2);
Map<String, Object> attributes2 = principal2.getAttributes();
out.println("<br>");
if (attributes2 != null)
{
out.println("username:" + attributes.get("username"));
out.println("<br>");
out.println("password:" + attributes2.get("password"));
out.println("<br>");
out.println("email:" + attributes2.get("email"));
out.println("<br>");
out.println("name:" + attributes2.get("name"));
out.println("<br>");
}
%>

说明:AsserionHolder工具怎么获取用户信息的?
回想下,我们是不是在客户端的程序中WEB.xml文件配置过如下信息
<filter> <filter-name>CAS Assertion Thread Local Filter</filter-name> <filter-class>org.jasig.cas.client.javafilter.util.AssertionThreadLocalFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Assertion Thread Local Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
再让我们看下AssertionThreadLocalFilter.java又是如何工作的
public final class AssertionThreadLocalFilter implements Filter {
public void init(final FilterConfig filterConfig) throws ServletException {
// nothing to do here
}
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpSession session = request.getSession(false);
final Assertion assertion = (Assertion) (session == null ? request.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) : session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION));
try {
AssertionHolder.setAssertion(assertion);
filterChain.doFilter(servletRequest, servletResponse);
} finally {
AssertionHolder.clear();
}
}
public void destroy() {
// nothing to do
}
我想大家应该看明白了吧
博客介绍了使用CAS作为单点登录服务器时,从CAS Server端获取更多用户信息的方法。包括配置属性attributeRepository、配置用户认证凭据转化的解析器、将添加的用户信息返回给客户端。还说明了客户端如何获取这些信息,涉及WEB.xml文件配置及相关工具的工作原理。
681

被折叠的 条评论
为什么被折叠?



