CAS-Server之Ticket体系

  • ticket是Server端与client端通信的票据,有了ticket服务才知道你是首次请求认证还是认证通过来验证的。
  • cas服务器默认实现了2种认证方式,一种是普通登录,也就是按照基本的cas流程认证,还有一种是代理认证,这种认证方式因为涉及到一个业务系统请求另一个业务系统资源所以复杂一些。
  • 基本认证流程cas提供了TicketGrantingTicket(TGT)和ServiceTicket(ST)两种Ticket,代理认证在基本认证基础上增加了ProxyGrantingTicket(PGT,PGTIOU)和ProxyTicket(PT)两种。

Ticket实体

Ticket接口

该接口定义了Ticket基本的属性,如id,isExpired(是否过期),CreationTime(创建时间),CountOfUses(当前ticket以被使用次数,每验证一次会加1),TicketGrantingTicket(每个Ticket实现都是基于TicketGrantingTicket)

Ticket分类

TicketGrantingTicket(TGT)

从Ticket接口可知TicketGrantingTicket是所有Ticket实现的基础(不包括自己),没有TicketGrantingTicket是不可能生成其他的Ticket。
那TicketGrantingTicket何时生成呢?先看下源码

public interface CentralAuthenticationService {
  //生成TicketGrantingTicket
  TicketGrantingTicket createTicketGrantingTicket(AuthenticationContext context)
}

可知,必须先有Authentication实例,才会生成TicketGrantingTicket,Authentication实例是用户信息认证成功后cas服务器创建的。

ServiceTicket(ST)

ServiceTicket是客户端进行验证的票据,服务端验证通过才会将用户信息返回给客户端。
ServiceTicket生成必须要ticketGrantingTicketId

public interface CentralAuthenticationService {
    //生成ServiceTicket
    ServiceTicket grantServiceTicket(String ticketGrantingTicketId, Service service, AuthenticationContext context)
    //验证ServiceTicket
    Assertion validateServiceTicket(String serviceTicketId, Service service) 
}
ProxyGrantingTicket(PGT,PGTIOU)

ProxyGrantingTicket继承TicketGrantingTicket,说明ProxyGrantingTicket只是一种特殊的TicketGrantingTicket,特殊点就是在代理认证模式下使用。
ProxyGrantingTicket是在代理端验证serviceTicket的时候生成的,代理端验证serviceTicket时除了传serviceTicketId还会传pgtUrl参数,表示接收PGT和PGTIOU的url,这点可看org.jasig.cas.web.AbstractServiceValidateController#handleRequestInternal方法。
代理端验证serviceTicket后,cas服务端除了返回assertion信息,还会返回pgtIou,代理端拿着这个pgtIou去存储PGT和PGTIOU映射的地方找到PGT,然后拿着PGT和targetService再次请求cas服务器(/proxy),返回ProxyTicket。具体可看代理流程序列图。

public interface CentralAuthenticationService {
  //生成ProxyGrantingTicket
  ProxyGrantingTicket createProxyGrantingTicket(String serviceTicketId, AuthenticationContext context)
}

org.jasig.cas.web.AbstractServiceValidateController#handleRequestInternal方法
//proxyHandler使用Cas20ProxyHandler
String proxyIou = null;
if (serviceCredential != null && this.proxyHandler.canHandle(serviceCredential)) {
    proxyIou = this.proxyHandler.handle(serviceCredential, proxyGrantingTicketId);
    ...省略其他代码
 }
ProxyTicket(PT)

ProxyTicket继承ServiceTicket,说明也是一种特殊的ServiceTicket,是给被代理端验证用的,代理端通过ProxyGrantingTicket获取到ProxyTicket后,请求被代理端带上该ProxyTicket,被代理端那着该ProxyTicket去cas服务器验证(/proxyValidate),验证过程同基本验证流程一样,返回assertion。

附上类图


TGT

ST

PGT

PT

Ticket存储

TicketRegistry接口

该接口定义了Ticket的增删改查,搜索整个工程在DefaultTicketRegistrySupport、TicketRegistryCleaner和CentralAuthenticationServiceImpl三个类中使用了该接口。

  • DefaultTicketRegistrySupport用于通过ticketGrantingTicketId去TicketRegistry中获取TicketGrantingTicket中的属性如Authentication、Principal、Attributes等。
  • TicketRegistryCleaner是一个Job,用于定时清理TicketRegistry中过期的Ticket。
  • CentralAuthenticationServiceImpl用于生成*Ticket比添加到TicketRegistry中。
DefaultTicketRegistry

TicketRegistry的默认实现,使用一个HashMap存储Ticket,这种在系统小的时候可以,系统数据多的时候就要考虑用第三方存储了,如数据库或缓存。

AbstractDistributedTicketRegistry

一个分布式Ticket存储实现(抽象类),具体采用哪种方式需要自己继承该类。该类中有getProxiedTicketInstance方法,用于生成一个ticket代理。


getProxiedTicketInstance

为什么要生成代理呢?
点开任意一个代理实现,发现代理类中部分方法添加了事务处理且在同种方法中多了一个updateTicket()方法,如下图,以TicketGrantingTicketDelegator为例


TicketGrantingTicketDelegator
  1. 这也很好理解,因为是对第三方储存的操作且分成了多个步骤所以叫加事务处理。至于增加updateTicket方法是因为,每次对Ticket的修改都会改变Ticket的状态,如previousLastTimeUsed、lastTimeUsed、countOfUses(见updateState方法)
  2. 那么重点来了,该怎么用。之前从DefaultTicketRegistry中取得都是原始Ticket,现在要改成代理Ticket,只需在自己的实现类中返回Ticket的方法中调用getProxiedTicketInstance方法将原始Ticket换成代理Ticket返回就行了,记住只在返回Ticket的方法中转换,更新和修改方法不变。只有两个方法getTicket(String ticketId)和getTickets()方法。
  3. 各个Ticket实体中已经加了JPA注解,当使用数据库存储时,可以将整个Ticket实体存到数据库,只需表字段和实体字段一一对应,CAS想的真是周到。

Ticket生成

TicketFactory接口
  //获取Ticket
  <T extends TicketFactory> T get(Class<? extends Ticket> clazz);
TicketGrantingTicketFactory接口
  //生成TicketGrantingTicket,默认实现DefaultTicketGrantingTicketFactory
  <T extends TicketGrantingTicket> T create(Authentication authentication);
ServiceTicketFactory接口
  //生成ServiceTicket,默认实现DefaultServiceTicketFactory
  <T extends Ticket> T create(TicketGrantingTicket ticketGrantingTicket,Service service,boolean credentialsProvided);
ProxyGrantingTicketFactory接口
  //生成ProxyGrantingTicket,默认实现DefaultProxyGrantingTicketFactory
  <T extends ProxyGrantingTicket> T create(ServiceTicket ticket, Authentication authentication);
ProxyTicketFactory接口
//生成ProxyTicket,默认实现DefaultProxyTicketFactory
<T extends Ticket> T create(ProxyGrantingTicket ticketGrantingTicket,Service service);

每个实现类中都有默认的TicketId生成器和ExpirationPolicy(过期策略),如果需要实现自己的在xml中替换就行了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容

  • 1. CAS 简介 1.1. What is CAS ? CAS ( Central Authenti...
    人在码途阅读 9,815评论 3 51
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,672评论 18 139
  • JAVA单点登录有好多种方式,譬如用cookie的domain做,用中间代理做等等,但都需要自行做许多开发工作。而...
    飞天的龙王阅读 4,134评论 3 9
  • 塞北江南忽变冷,鹏城独暖慰吾心。朵梅酷爱三冬晚,片雪盛情一衲深。安处为乡成追忆,老来委命候佳音。耿怀不寐酬诗兴,短...
    芝兰室主阅读 510评论 0 6
  • 过于妖艳 滴出血的浪漫 没有花语 故事总是带刺 红,是鲜活的红 刺,是锋利的尖刀 还没触碰 就已 鲜血淋漓 泪流不止
    忆清欢阅读 443评论 0 2