`

单点登录 - CAS【四】获取更全面的用户信息

 
阅读更多

       我们再使用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
    }

 

我想大家应该看明白了吧

 

 

  • 大小: 2 KB
  • 大小: 9.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics