一旦CAS SERVER验证成功后,我们就会跳转到客户端中去。跳转到客户端去后,大家想一想,客户端总要获取用户信息吧,不然客户端是怎么知道登录的是哪个用户。那么客户端要怎么获取用户信息呢?

其实验证成功,跳转客户端这个过程中,CAS SERVER 会返回登录的相关信息给客户端,客户端只要进行获取,就能知道登录的具体是哪个用户了。不过CAS 默认只返回用户账号给客户端,那么怎么定义CAS SERVER返回的信息呢? 这就是本篇具体讲解的内容了,大家听我慢慢道来。

相关接口                                                               

在开始时,我们先了解下有关相关的几个接口

  • Credentials
  • Principal
  • IPersonAttributeDao
  • PrincipalResolver

Credentials                                                    

  Credentials (org.jasig.cas.authentication.Credentials)接口,我们在上一篇其实有使用过,我们当时有用过一个叫 UsernamePasswordCredential 的类,就是实现了Credentials接口。这个接口是用来定义我们登录页上输入的认证信息的,比如用户名、密码、验证码等,可以理解为用户认证的相关凭据。

Principal                                                     

  Principal (org.jasig.cas.authentication.principal.Principal) 接口,这个主要是用来保存用户认证后的用户信息,信息保存在一个Map中。

IPersonAttributeDao                                              

  IPersonAttributeDao (org.jasig.services.persondir.IPersonAttributeDao) 接口,这个是用来定义我们需要返回给客户端相关信息的接口,CAS SERVER 默认有提供许多实现,比如

  • LdapPersonAttributeDao :通过查询 LDAP 目录 ,来返回信息
  • SingleRowJdbcPersonAttributeDao : 通过JDBC SQL查询,来返回信息

等等,还有许多,大家可以参考源码中的实现,CAS SERVER 提供了各种功能的实现,有时候我们可以直接使用这个现成的就行了。

PrincipalResolver                                                 

  PrincipalResolver(org.jasig.cas.authentication.principal.PrincipalResolver) 接口,上面有说到 Credentials 是从登录页面上进行获取相关用户信息的。那么认证成功后,怎么把Credentials里面的信息转换到 Principal  中呢,这就是这个接口的作用了。由于认证本身是没有返回用户信息的,只是确定认证是通过还是没有通过。这时还要用到我们上面的IPersonAttributeDao 接口,在这接口中我们就可以定义我们需要返回的信息了。

这接口中有两个方法

  • resolve : 解析Credentials中的信息,返回 Principal 接口
  • supports : 判断Credentials 是否支持 Principal 协议。

ps: 在3.x版本中没有 PrincipalResolver接口,对应的是CredentialsToPrincipalResolver, PrincipalResolver这个是在4.0版本中加入的,大家要注意。

流程                                           

相关接口讲解后,大家应该对怎么返回信息有个大概的思路了。没错就是实现上面所说的 IPersonAttributeDao 、PrincipalResolver 接口 。下面根据代码讲解下具体的一个流程:

首先打开 deployerConfigContext.xml 文件,看下面的定义:

 <!--| Resolves a principal from a credential using an attribute repository that is configured to resolve| against a deployer-specific store (e.g. LDAP).--><bean id="primaryPrincipalResolver"class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" ><property name="attributeRepository" ref="attributeRepository" /></bean><!--Bean that defines the attributes that a service may return.  This example uses the Stub/Mock version.  A real implementationmay go against a database or LDAP server.  The id should remain "attributeRepository" though.+--><bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"p:backingMap-ref="attrRepoBackingMap" /><util:map id="attrRepoBackingMap"><entry key="uid" value="uid" /><entry key="eduPersonAffiliation" value="eduPersonAffiliation" /> <entry key="groupMembership" value="groupMembership" /></util:map>

//PersonDirectoryPrincipalResolver 部分源码

public final Principal resolve(final Credential credential) {logger.debug("Attempting to resolve a principal...");String principalId = extractPrincipalId(credential);  //extractPrincipalId 方法从credential中抽取id//省略...final IPersonAttributes personAttributes = this.attributeRepository.getPerson(principalId);  //根据IPersonAttributeDao 中的getPerson 获取返回的属性final Map<String, List<Object>> attributes;//最终返回 Principal return new SimplePrincipal(principalId, convertedAttributes);}    

具体流程:

1.从上面的deployerConfigContext.xml 配置我们可以看到,CAS 默认配置了一个叫做 PersonDirectoryPrincipalResolver 的类,在 这个类的 resolve  方法中有调用 extractPrincipalId 这个方法,这个方法传入一个 Credentials 类型的参数,默认调用的是Credentials  的getId() 方法,CAS默认是返回用户的userName,即登录账号。不过getId()  这个方法的实现我们可以在上一章中指定的UsernamePasswordCredential 类中自定义,一般是定义成返回用户的userId或者其他唯一键,因为我们如果知道了用户的userId,那么就可以根据这个从数据库中查询中用户的一些具体信息了,进而就可以组成我们需要返回的信息。

2. 继续往下看源码,接着在 PersonDirectoryPrincipalResolver  中有注入一个 attributeRepository 属性,这个就是上面的IPersonAttributeDao 接口,然后在resolve方法中调用了 IPersonAttributeDao 接口 的getPerson方法,还传入了一个参数principalId,其实这个传入的参数就是我们上面 getId() 返回的值。

所以其实我们只要实现我们需要的 IPersonAttributeDao  就可以了。 下面给一个简单的IPersonAttributeDao  例子:

public class BlogStubPersonAttributeDao extends StubPersonAttributeDao {@Overridepublic IPersonAttributes getPerson(String uid) {Map<String, List<Object>> attributes = new HashMap<String, List<Object>>();attributes.put("userid", Collections.singletonList((Object)uid));attributes.put("cnblogUsername", Collections.singletonList((Object)"http://www.cnblogs.com/vhua"));attributes.put("cnblogPassword", Collections.singletonList((Object)"123456"));attributes.put("test", Collections.singletonList((Object)"test"));return new AttributeNamedPersonImpl(attributes);}}

这边传入的uid 默认是用户的登录名,我们这边没有做修改,直接用默认的。

这边是只是测试用,所以就直接写死了,实际开发肯定是需要在数据库或者LDAP中进行查询后,然后组装成需要的信息 。

然后在 deployerConfigContext.xml 中修改

<bean id="primaryPrincipalResolver"class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" ><property name="attributeRepository" ref="attributeRepository" /></bean>
<!-- 修改前 --><bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"p:backingMap-ref="attrRepoBackingMap" /><util:map id="attrRepoBackingMap"><entry key="uid" value="uid" /><entry key="eduPersonAffiliation" value="eduPersonAffiliation" /> <entry key="groupMembership" value="groupMembership" /></util:map>
<!-- 修改前 end-->

<!--修改后--><bean id="attributeRepository" class="org.jasig.services.persondir.support.BlogStubPersonAttributeDao" />
<!--修改后  end-->

3. 修改完成后,我们还需要在 casServiceValidationSuccess.jspcas-server-webapp\src\main\webapp\WEB-INF\view\jsp\protocol\2.0\casServiceValidationSuccess.jsp)

添加一段代码(下面红色部分):

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'><cas:authenticationSuccess><cas:user>${fn:escapeXml(assertion.primaryAuthentication.principal.id)}</cas:user>    <!-- 这段 -- ><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><!-- 这段 end-- >

<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>

4. 接下来 在客户端设置信息的接收,我们直接在index.jsp中测试一下:

在Java中可以通过下面的方式获取

AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();

Map attributes = principal.getAttributes();

String xxx=attributes .get("xxx");

...

<!DOCTYPE html">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>返回值测试</title>
</head>
<body><% request.setCharacterEncoding("UTF-8");AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();Map attributes = principal.getAttributes();String userid=(String)attributes.get("userid"); String cnblogUsername = (String)attributes.get("cnblogUsername"); String cnblogPassword = (String)attributes.get("cnblogPassword"); String test=(String)attributes.get("test"); %><div>飞奔的蜗牛博客:返回值演示</div><ul><li>userid:<%= userid%></li><li>username:<%= cnblogUsername%></li><li>password:<%= cnblogPassword%></li><li>test:<%= test%></li></ul>
</body>
</html>

效果                                           

好了,我们登录运行看看结果。

大家看到没,已经获取成功了,在CAS SERVER那边设置的信息,我们正常获取到了 。大家可以根据业务的需要,返回相关的信息。然后在客户端进行操作。

转自:http://www.cnblogs.com/vhua/p/cas_4.html

转载于:https://www.cnblogs.com/hujie-developer/p/6265305.html

CAS学习笔记(三)—— SERVER登录后用户信息的返回相关推荐

  1. imos 学习笔记三 下载指定时间段视频信息 c#

    下载指定时间段视频信息 -1 初始化 -2 加密密码 -3 登录 *4 启动播放器 *5 查询录像文件 6 获取录像文件的url 7 打开下载媒体流 8 设置下载媒体流厂商标志 9 开始下载媒体流 1 ...

  2. CAS学习笔记五:SpringBoot自动/手动配置方式集成CAS单点登出

    本文目标 基于SpringBoot + Maven 分别使用自动配置与手动配置过滤器方式实现CAS客户端登出及单点登出. 本文基于<CAS学习笔记三:SpringBoot自动/手动配置方式集成C ...

  3. JavaWeb-综合案例(用户信息)-学习笔记02【登录功能】

    Java后端 学习路线 笔记汇总表[黑马程序员] JavaWeb-综合案例(用户信息)-学习笔记01[列表查询] JavaWeb-综合案例(用户信息)-学习笔记02[登录功能] JavaWeb-综合案 ...

  4. K8S 学习笔记三 核心技术 Helm nfs prometheus grafana 高可用集群部署 容器部署流程

    K8S 学习笔记三 核心技术 2.13 Helm 2.13.1 Helm 引入 2.13.2 使用 Helm 可以解决哪些问题 2.13.3 Helm 概述 2.13.4 Helm 的 3 个重要概念 ...

  5. python爬虫学习笔记2模拟登录与数据库

    前言 为了加入学校里面一个技术小组,我接受了写一个爬取学校网站通知公告的任务.这个任务比以前写的爬虫更难的地方在于,需要模拟登录才能获得页面,以及将得到的数据存入数据库. 本文按照日期来记录我完成任务 ...

  6. J2EE学习笔记三:EJB基础概念和知识 收藏

    J2EE学习笔记三:EJB基础概念和知识 收藏 EJB正是J2EE的旗舰技术,因此俺直接跳到这一章来了,前面的几章都是讲Servlet和JSP以及JDBC的,俺都懂一些.那么EJB和通常我们所说的Ja ...

  7. MySQL学习笔记07【事务、用户管理和权限管理】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  8. python3常用模块_Python学习笔记三(常用模块)

    Python 学习笔记三 (常用模块) 1.os模块 os模块包装了不同操作系统的通用接口,使用户在不同操作系统下,可以使用相同的函数接口,返回相同结构的结果. os.name:返回当前操作系统名称( ...

  9. Spring框架学习笔记(三)(AOP,事务管理)

    Spring框架学习笔记(三) 九.AOP 9.1 AOP的注解配置 (1) 新建计算器核心功能(模拟:不能在改动核心代码) (2) 建立一个普通的Java类写增强代码(面向切面编程),使用Sprin ...

  10. SurfaceFlinger学习笔记(三)之SurfaceFlinger进程

    概述 本系列是基于android Q 即android10 SurfaceFlinger学习笔记(一)应用启动流程 SurfaceFlinger学习笔记(二)之Surface SurfaceFling ...

最新文章

  1. VR/AR标准委员会成立,宣布全新的标准OpenXR
  2. 互联网1分钟 | 0327 华为P30系列发布;微信公号直播工具大范围开放内测资格
  3. redis版本_全球首发|阿里云正式推出云数据库Redis6.0版本
  4. 【ZOJ - 3780】Paint the Grid Again(拓扑排序,图论,证明性质)
  5. oracle 从右往左截取_截取GIF、调分辨率、快捷拨号,三星这些功能让人爱不释手...
  6. Digilent提供的PmodOLEDrgb驱动程序
  7. Ubuntu 16.04中的Grub更新警告
  8. Windows下 Anaconda + VScode Python 环境搭建 多图 非常详细
  9. Vue 项目在 IE11 中数据更改后页面数据无变化
  10. 一个Lumen多层拆分手记
  11. 40+ 张最全 Linux / C / C++ 思维导图,收藏!
  12. linux下挂载移动硬盘(ntfs格式)
  13. 远程控制软件teamview好用么?
  14. am335x LCD调节背光
  15. Xmind 2022 Mac版 思维导图软件
  16. bat批处理静默自动安装证书
  17. 新浪短链接 新浪t.cn短链接在线生成生成工具
  18. Phalloidin——Acti-stain555鬼笔环肽研究
  19. 计算机一级考试2018知识点,2018年全国计算机一级ms office考试内容
  20. 【Cheatsheet】Java的常用代码(以及eclipse技巧)

热门文章

  1. Webpack使用教程五(Babel)
  2. UPS输出连接要求IEC C320 C13,输入连接要求(6)IEC 320 C14
  3. Data Pump -- Example
  4. smart link和聚合链路综合实验
  5. options请求_HTTP 协议 POST 请求,为什么会有一个 OPTION?
  6. php 压缩及解压文件,php zip文件的解压与压缩
  7. java笔记之过滤器
  8. git单独删除某个文件的所有历史记录
  9. android c vector用法,c – 使用std:vector作为低级缓冲区
  10. Collectors.maxBy()和minBy()