CAS返回对象的更多属性Assertion.getPrincipal().getAttributes()

服务器,在返回给客户端用户信息时,默认只返回用户名(我们已经修改成ID).但有时我们需要更多的属性信息,如用户名。

则应做如下修改:

用户登录成功以后,CAS使用一个credentialsToPrincipalResolvers将credentials转成Principal对象,此对象只有一个实现类如下.
SimplePrincipal的构造方法接收两个参数,一个是用户的id,一个为用户的其他属性。用户的ID默认为用户登录时使用的用户名,前面第4点已经讲过如何将用户的name换成用户的id返回给客户端。为了给客户端返回更多的属性,我们必须要给Principal的构造方法传递第二个参数,它是一个Map<String,Object>类型。

具体代码如下:

package cn.itcast.pubs;

import java.util.HashMap;

import java.util.Map;


import javax.sql.DataSource;

import org.jasig.cas.authentication.principal.Credentials;

import org.jasig.cas.authentication.principal.CredentialsToPrincipalResolver;

import org.jasig.cas.authentication.principal.Principal;

import org.jasig.cas.authentication.principal.SimplePrincipal;

import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;

import org.springframework.jdbc.core.JdbcTemplate;

public class MyCredentialsToPrincipalResolver implements CredentialsToPrincipalResolver {

private DataSource dataSource;//查询数据库用

@Override

public Principal resolvePrincipal(Credentials credentials) {

System.err.println("将凭据转换成被代理人:"+credentials);

UsernamePasswordCredentials up = //强制类型转换

(UsernamePasswordCredentials) credentials;

String name = up.getUsername();

String pwd  = up.getPassword();

String sql = "select id from users2 where u2_name=? and u2_pwd=?"; //查询id

String id  = null;

try{

id=new JdbcTemplate(getDataSource()).queryForObject(sql, String.class, name,pwd);

if(id!=null){

//封装其他信息

Map<String,Object> attrs = new HashMap<String,Object>();

attrs.put("username",name);

attrs.put("pwd",pwd);

Principal p = new SimplePrincipal(id,attrs);//封装成包含id的Principal对象

System.err.println("生成的属性值是::"+attrs);

return p;

}

}catch(Exception e){

e.printStackTrace();

}

return null;

}


@Override

public boolean supports(Credentials credentials) {

boolean boo =  //判断是否是用户和密码凭据 

UsernamePasswordCredentials.class.isAssignableFrom(credentials.getClass());

return boo;

}

public DataSource getDataSource() {

return dataSource;

}


public void setDataSource(DataSource dataSource) {

this.dataSource = dataSource;

}

}


但,它并不会马上显示到客户端,如果要显示到客户端,因为服务器验证成功以后,是通过xml形式将结果传递给客户端的,xml的生成由casServiceValidationSuccess.jsp文件负责。它的具体构造应该是以下形式:

<cas:serviceResponse

    xmlns:cas='http://www.yale.edu/tp/cas'>

    <cas:authenticationSuccess>

       <cas:user>U001</cas:user>

       <cas:attributes>

              <cas:pwd>1234</cas:pwd>

              <cas:username>Jack</cas:username>

       </cas:attributes>

    </cas:authenticationSuccess>

</cas:serviceResponse>

在上面的代码中,cas:attributes元素是笔者添加的,客户端的的Filter在接收到上述的XML以后,会将css:attributes中的属性解析出来,放到AttirubtePrincipal的attributes属性中去(或是放到Asseration的attributes中去,两个只会放一个)。

 

所以,组成上面的<cas :attributes>元素中的内容,就成了如何传递更多属性的关键,在修改了MyCredentialsToPrincipalResolver的代码以后,然后还必须要修改casServiceValidationSuccess.jsp的代码如下:

<%@ page session="false"contentType="text/xml; charset=UTF-8"%><%@taglib

    prefix="c"uri="http://java.sun.com/jsp/jstl/core"%><%@taglib

    uri="http://java.sun.com/jsp/jstl/functions"prefix="fn"%><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:iftest="${not emptypgtIou}">

           <cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket>

       </c:if>

       <c:iftest="${fn:length(assertion.chainedAuthentications) > 1}">

           <cas:proxies>

              <c:forEachvar="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:attributes>

           <c:forEach

               items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}"

              var="attr">

              <cas:${attr.key}>${attr.value}</cas:${attr.key}>

           </c:forEach>

       </cas:attributes>

    </cas:authenticationSuccess>

</cas:serviceResponse>

 

然后修改deployerConfigContext.xml文件,将最后一个配置项:serviceRegistryDao中的所有属性全部删除或是注销。

或者修改如下配置

    <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
        <property name="registeredServices">
            <list>
                <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                    <property name="id" value="0" />
                    <property name="name" value="HTTP" />
                    <property name="description" value="Only Allows HTTP Urls" />
                    <property name="serviceId" value="http://**" />          
                </bean>

                <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                    <property name="id" value="1" />
                    <property name="name" value="HTTPS" />
                    <property name="description" value="Only Allows HTTPS Urls" />
                    <property name="serviceId" value="https://**" />              
                </bean>

                <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                    <property name="id" value="2" />
                    <property name="name" value="IMAPS" />
                    <property name="description" value="Only Allows HTTPS Urls" />
                    <property name="serviceId" value="imaps://**" />             
                </bean>

                <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                    <property name="id" value="3" />
                    <property name="name" value="IMAP" />
                    <property name="description" value="Only Allows IMAP Urls" />
                    <property name="serviceId" value="imap://**" />               
                </bean>
            </list>
        </property>


为:

 

  <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
        <property name="registeredServices">
            <list>
                <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                    <property name="id" value="0" />
                    <property name="name" value="HTTP" />
                    <property name="description" value="Only Allows HTTP Urls" />
                    <property name="serviceId" value="http://**" />
                    <property name="ignoreAttributes" value="true" />
                </bean>

                <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                    <property name="id" value="1" />
                    <property name="name" value="HTTPS" />
                    <property name="description" value="Only Allows HTTPS Urls" />
                    <property name="serviceId" value="https://**" />    
                    <property name="ignoreAttributes" value="true" />
                </bean>

                <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                    <property name="id" value="2" />
                    <property name="name" value="IMAPS" />
                    <property name="description" value="Only Allows HTTPS Urls" />
                    <property name="serviceId" value="imaps://**" />
                    <property name="ignoreAttributes" value="true" />
                </bean>

                <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                    <property name="id" value="3" />
                    <property name="name" value="IMAP" />
                    <property name="description" value="Only Allows IMAP Urls" />
                    <property name="serviceId" value="imap://**" />
                    <property name="ignoreAttributes" value="true" />
                </bean>
            </list>
        </property>


这个bean中的RegisteredServiceImplignoreAttributes属性将决定是否添加attributes属性内容,默认为false:不添加,只有去掉这个配置,
cas server
才会将获取的用户的附加属性添加到认证用的Principalattributes中去。

 

然后即可以在页面上通过以下方式获取用户的其他属性:

    <%

       Assertion assertion = AssertionHolder.getAssertion();

       AttributePrincipal ap =  assertion.getPrincipal();   //获取AttributePrincipal对象,这是客户端对象

       String name = ap.getName();

       Map<String,Object> att = ap.getAttributes();//获取属性值,为一个Map类型。

       out.print("<br/>"+name);

       out.print("<br/>"+att);

%>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
vc++全版本组件大全 VC++运行时(Visual C++ Runtime)是VC++开发环境中用于支持C和C++程序运行的基础库集合。这些库包含了执行C/C++程序所必需的基本函数和数据结构,例如内存管理、字符串操作、输入输出处理、异常处理等。VC++运行时库分为静态库和动态库两种形式,以适应不同类型的项目需求。 静态链接库 vs 动态链接库 静态链接库(Static Linking Libraries):在编译时,静态库的代码会被直接嵌入到最终生成的可执行文件中。这意味着每个使用静态库的程序都会包含库代码的一个副本,导致最终程序的体积较大,但不需要外部库文件支持即可独立运行。在VC++中,静态链接库的例子有LIBC.lib(用于单线程程序)和LIBCMT.lib(用于多线程程序)。 动态链接库(Dynamic Link Libraries):与静态链接相反,动态库的代码并不直接加入到应用程序中,而是在程序运行时被加载。这使得多个程序可以共享同一份库代码,节省了系统资源。VC++的动态运行时库主要通过msvcrt.dll(或其变体,如MSVCRTD.dll用于调试版本)实现,与之配套的导入库(Import Library)如CRTDLL.lib用于链接阶段。 运行时库的版本 VC++运行时库随着Visual Studio版本的新而发展,每个版本都可能引入新的特性和优化,同时保持向后兼容性。例如,有VC++ 2005、2008、2010直至2019等多个版本的运行时库,每个版本都对应着特定的开发环境和Windows操作系统。 重要性 VC++运行时对于确保程序正确运行至关重要。当程序在没有安装相应运行时库的计算机上执行时,可能会遇到因缺失DLL文件(如MSVCP*.dll, VCRUNTIME*.dll等)而导致的错误。因此,开发完成后,通常需要分发相应的VC++ Redistributable Packages给最终用户安装,以确保程序能够在目标系统上顺利运行。 安装与部署 安装VC++运行时库通常是通过Microsoft提供的Redistributable Packages完成的,这是一个简单的过程,用户只需运行安装程序即可自动安装所需组件。对于开发者而言,了解和管理不同版本的运行时库对于确保应用程序的广泛兼容性和可靠性是必要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值