从cas server登录成功后,默认只能从casclient得到用户名。但程序中也可能遇到需要得到更多如姓名,手机号,email等更多用户信息的情况。

cas client拿到用户名后再到数据库中查询,的确可以得到关于该用户的更多信息。

但是如果用户登录成功后,直接从cas server返回给casclient用户的详细信息,这也是一个不错的做法。这个好处,尤其是在分布式中得以彰显,cas
server可以把用户信息传递给各个应用系统,如果是上面那种做法,那么各个系统得到用户名后,都得去数据库中查询一遍,无疑是一件重复性工作。

文章中 CAS 基础环境:

cas-server-3.5.2

cas-client-3.2.1

 一、首先需要配置属性attributeRepository

首先,你需要到WEB-INF目录找到 deployerConfigContext.xml文件,同时配置attributeRepository
如下:

<bean  class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"id="attributeRepository">
<constructor-argindex="0" ref="casDataSource"/>
<constructor-argindex="1" value="select * from userinfo where {0}"/>
<propertyname="queryAttributeMapping">
<map>
<entrykey="username" value="loginname"/> // 这里的key需写username和登录页面一致,value对应数据库用户名字段
</map>
</property>
<propertyname="resultAttributeMapping">
<map>
// <!--key为对应的数据库字段名称,value为提供给客户端获取的属性名字,系统会自动填充值-->
<entrykey="id" value="id"/>
<entrykey="mobile" value="mobile"/>
<entrykey="email" value="email"/>
</map>
</property>
</bean>

其中:

切记:查询出来的字段名中间不能使用 _ (下划线),否则获取不到数据,如 cell_phone 需要 设置别名为 cellPhone.

queryAttributeMapping是组装sql用的查询条件属性,上述配置后,结合封装成查询sql就是 select *from userinfo where loginname=#username#

resultAttributeMapping是sql执行完毕后返回的结构属性, key对应数据库字段,value对应客户端获取参数。

如果要组装多个查询条件,需要加上下面这个,默认为AND

<property name="queryType">

<value>OR</value>

</property>

二、配置用户认证凭据转化的解析器

也是在 deployerConfigContext.xml 中,找到credentialsToPrincipalResolvers,为UsernamePasswordCredentialsToPrincipalResolver 注入 attributeRepository,那么attributeRepository
就会被触发并通过此类进行解析,红色为新添部分。

<propertyname="credentialsToPrincipalResolvers">
<list>
<beanclass="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver">
<property name="attributeRepository"ref="attributeRepository"/>
</bean>
<beanclass="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver"/>
</list>
</property>

 三、配置InMemoryServiceRegistryDaoImpl属性 registeredServices

修改 deployerConfigContext.xml 中的 org.jasig.cas.services.InMemoryServiceRegistryDaoImpl的 属性 registeredServices。修改 registeredServices  的allowedAttributes属性值,将需要在客户端显示的列值加上。

<bean  id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
<property name="registeredServices">
<list>
<beanclass="org.jasig.cas.services.RegexRegisteredService">
<property name="id"value="0" />
<property name="name"value="HTTP and IMAP" />
<property name="description"value="Allows HTTP(S) and IMAP(S) protocols" />
<property name="serviceId"value="^(https?|imaps?)://.*" />
<propertyname="evaluationOrder" value="10000001" />
<propertyname="allowedAttributes"> // 客户端需要使用的对象的属性名称
<list>
<value>uid</value>
<value>email</value>
<value>mobile</value>
<value>birth</value>
<value>isMarry</value>
<value>userno</value>
<value>login_account</value>
</list>
</property>
</bean>

【提示】网上说此bean中的ignoreAttributes属性默认是不添加用户信息,查看了 CAS 3.5.2版本的 AbstractRegisteredService 源码后,发现其默认值就是false,即:添加属性后,客户端就可见了

四、配置与客户端交互的xml信息

修改WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp。在server验证成功后,这个页面负责生成与客户端交互的xml信息,在默认的casServiceValidationSuccess.jsp中,只包括用户名,并不提供其他的属性信息,因此需要对页面进行扩展,如下,红色为新添加部分

<cas:serviceResponsexmlns: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="${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>
<c:if test="${not empty pgtIou}">
<cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket>
</c:if>
<c:iftest="${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>

通过完成上面四个步骤的配置后,server端的工作就完成了,那么如何在客户端获取这些信息呢?下面进行说明:

客户端获取用户信息

cas client获取用户信息:

AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();
Map attributes = principal.getAttributes();
String email=attributes .get("email");

shiro集成后获取用户信息:

和shiro集成后,因为cas client将casFilter交给了shiroFilter,所以在通过shiro对象时可以用户信息的:
Subject subject = SecurityUtils.getSubject();

List list = subject.getPrincipals().asList();
String name = (String) list.get(0);
Map<String, Object> info = (Map<String, Object>)list.get(1); String age = info.get("age").toString();
作者:tcl_6666 发表于2014-3-27 11:10:26 原文链接
阅读:984 评论:11 查看评论

[原]基于CAS实现单点登录(SSO):登录成功后,cas client如何返回更多用户信息的更多相关文章

  1. 单点登录(一)-----理论-----单点登录SSO的介绍和CAS+选型

    什么是单点登录(SSO) 单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无须多次登录. 单点登录(Single Sign On),简称为 ...

  2. Spring Security 解析(六) —— 基于JWT的单点登陆(SSO)开发及原理解析

    Spring Security 解析(六) -- 基于JWT的单点登陆(SSO)开发及原理解析   在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把 ...

  3. spring 基于xml的申明式AspectH中的后置通知的返回值获取

    spring 基于xml的申明式AspectH中的后置通知的返回值获取 1. 配置文件 <aop:config> <aop:aspect ref="myAspect&quo ...

  4. [转]单点登录SSO学习——CAS协议内容

    作者:anmaler 本文转自:http://blog.zhaojunling.me/p/24 CAS中文文档甚少,这篇文章对CAS接口参数有比较清楚的说明,排版也不错查阅舒适 在当前互联网产品中使用 ...

  5. cas sso单点登录系列2:cas客户端和cas服务端交互原理动画图解,cas协议终极分析

    转:http://blog.csdn.net/ae6623/article/details/8848107 1)PPT流程图:ppt下载:http://pan.baidu.com/s/1o7KIlom ...

  6. SSO单点登录系列2:cas客户端和cas服务端交互原理动画图解,cas协议终极分析

    落雨 cas 单点登录 一.用户第一次访问web1应用. ps:上图少画了一条线,那一条线,应该再返回来一条,然后再到server端,画少了一步...谢谢提醒.而且,重定向肯定是从浏览器过去的.我写的 ...

  7. 单点登录 SSO(Single Sign-On)的实现原理

    为什么要 SSO? 企业的信息化过程是一个循序渐进的过程,这就造成在企业的不同时期,根据业务和发展需要,构建了多个应用程序,而这些应用程序在功能.设计和技术可能都有所不同,就形成了各自独立的用户库和用 ...

  8. 单点登录系统CAS筹建及取得更多用户信息的实现

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  9. 基于IdentityServer4的单点登录——项目基本结构与流程

    组成 IdentityServer,Api和Client(客户端,asp .net core)本文以官方demo:https://github.com/IdentityServer/IdentityS ...

随机推荐

  1. js删除数组里的某个元素

    首先可以给js的数组对象定义一个函数,用于查找指定的元素在数组中的位置,即索引,代码为: Array.prototype.indexOf = function(val) { for (var i = ...

  2. PHP框架学习之Laravel安装

    自从接触PHP以来一直使用Yii,感觉Yii实现功能比较简单,是一个很不错的框架.最近由于工作的原因开始研究Laravel5,不得不说我在第一步安装就被坑着了,下面就是我痛苦的学习成果.Laravel ...

  3. SurfaceView绘图机制

    一.为什么需要用SurfaceView绘图,不直接继承View绘图 它的特性是:可以在主线程之外的线程中向屏幕绘图上.这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度.在游戏开发 ...

  4. php 文件操作类

    class fileInit { /** * 创建空文件 * @param string $filename 需要创建的文件 * @return */ public function create_f ...

  5. IO-04. 混合类型数据格式化输入

    /** *A4-IO-04. 混合类型数据格式化输入 *C语言实现 *测试已通过 */ #include "stdio.h" int main() { float m1,m2; i ...

  6. Delphi RichEdit的内容保存为图片

    uses RichEdit; {将RichEdit1的内容保存为图片,此函数也适合于RxRichEdit,即RichEdit: TRxRichEdit}procedure RichEditToCanv ...

  7. [11-2] adaboost理解

    以二分类问题为例({-1,+1}) adaboost步骤: 1.初始化u1=(1/N,1/N,-,1/N) 2.找到h,使最小化,记该h为g:计算作为该g的权重 3.更新ui: 4.重复2,3得到T个 ...

  8. python cmd 模块

    command模块用于执行以字符串形式指定的简单系统命令,并将其输出以字符串形式返回.此模块尽在unix系统上有效.这个模型提供的功能与在unix shell脚本使用的反引号(就是~这个键下的那个反引 ...

  9. Android 仿微信滑动删除

    做这个功能主要是项目需要:找了很多资料但是效果都不理想,后来就自己研究写了一个,拿出来共享给大家,贴上代码大家慢慢看看,还是比较容易懂的. 主要代码: package com.zbq.widget; ...

  10. Java面试题之Class.forName的作用

    按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类, ...