前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于Redis缓存的单点登录SSO

基于Redis缓存的单点登录SSO

作者头像
tunsuy
发布2022-10-27 09:50:20
4280
发布2022-10-27 09:50:20
举报
文章被收录于专栏:有文化的技术人

术语

CAS系统中一般涉及多种票据,以及相关术语,以下详细介绍介绍。

  • Ticket-granting cookie(TGC):存放用户身份认证凭证的cookie,在浏览器和CAS Server间通讯时使用,并且只能基于安全通道传输(Https),是CAS Server用来明确用户身份的凭证
  • Service ticket(ST):服务票据,服务的惟一标识码,由CAS Server发出(Http传送),ST是CAS为用户签发的访问某service的票据。用户访问service时,service发现用户没有ST,则要求用户去CAS获取ST。用户向CAS发出获取ST的请求,如果用户的请求中包含cookie,则CAS会以此cookie值为key查询缓存中有无TGT,如果存在TGT,则用此TGT签发一个ST,返回给用户。用户凭借ST去访问service,service拿ST去CAS验证,验证通过后,允许用户访问资源。一个特定的服务只能有一个惟一的ST
  • Proxy-Granting ticket(PGT):Proxy Service的代理凭据。用户通过CAS成功登录某一Proxy Service后,CAS生成一个PGT对象,缓存在CAS本地,同时将PGT的值(一个UUID字符串)回传给Proxy Service,并保存在Proxy Service里。Proxy Service拿到PGT后,就可以为Target Service(back-end service)做代理,为其申请PT。
  • Proxy-Granting Ticket I Owe You(PGTIOU): PGTIOU是CAS协议中定义的一种附加票据,它增强了传输、获取PGT的安全性。PGT的传输与获取的过程:Proxy Service调用CAS的serviceValidate接口验证ST成功后,CAS首先会访问pgtUrl指向的https url,将生成的PGT及PGTIOU传输给proxy service,proxy service会以PGTIOU为key,PGT为value,将其存储在Map中;然后CAS会生成验证ST成功的xml消息,返回给Proxy Service,xml消息中含有PGTIOU,proxy service收到Xml消息后,会从中解析出PGTIOU的值,然后以其为key,在map中找出PGT的值,赋值给代表用户信息的Assertion对象的pgtId,同时在map中将其删除。
  • Proxy Ticket (PT):PT是用户访问Target Service(back-end service)的票据。如果用户访问的是一个Web应用,则Web应用会要求浏览器提供ST,浏览器就会用cookie去CAS获取一个ST,然后就可以访问这个Web应用了。如果用户访问的不是一个Web应用,而是一个C/S结构的应用,因为C/S结构的应用得不到cookie,所以用户不能自己去CAS获取ST,而是通过访问proxy service的接口,凭借proxy service的PGT去获取一个PT,然后才能访问到此应用。

其它说明如下:

  • Ticket Granting ticket(TGT):TGT是CAS为用户签发的登录票据,拥有TGT,用户就可以证明自己在CAS成功登录过。TGT封装Cookie值以及此Cookie值对应的用户信息。用户在CAS认证成功后,CAS生成cookie(叫TGC),写入浏览器,同时生成一个TGT对象,放入自己的缓存,TGT对象的ID就是cookie的值。当HTTP再次请求到来时,如果传过来的有CAS生成的cookie,则CAS以此cookie值为key查询缓存中有无TGT ,如果有的话,则说明用户之前登录过,如果没有,则用户需要重新登录。
  • Authentication service(AS):认证用服务,索取Credentials,发放TGT;
  • Ticket-granting service (TGS):票据授权服务,索取TGT,发放ST;
  • KDC( Key Distribution Center ):密钥发放中心;

CAS 基本原理

结构体系

从结构体系看, CAS 包括两部分:CAS Server 和 CAS Client 。

1、CAS Server

CAS Server 负责完成对用户的认证工作 , 需要独立部署 , CAS Server 会处理用户名 / 密码等凭证 (Credentials) 。

2、CAS Client

负责处理对客户端受保护资源的访问请求,需要对请求方进行身份认证时,重定向到 CAS Server 进行认证。(原则上,客户端应用不再接受任何的用户名密码等 Credentials )。

CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。

CAS 原理和协议

基础模式

SSO 访问流程主要有以下步骤:

  • 访问服务:SSO客户端发送请求访问应用系统提供的服务资源。
  • 定向认证:SSO客户端会重定向用户请求到SSO服务器。
  • 用户认证:用户身份认证。
  • 发放票据:SSO服务器会产生一个随机的Service Ticket。
  • 验证票据:SSO服务器验证票据Service Ticket的合法性,验证通过后,允许客户端访问服务。
  • 传输用户信息:SSO服务器验证票据通过后,传输用户认证结果信息给客户端。

通俗来说,就是这样一个流程:用户通过浏览器访问应用服务器,应用服务器后端发现没有携带ST,则会要求浏览器重定向到cas server去获取ST,cas server发现浏览器没有携带cookie,而是通过用户名密码请求过来的,请通过用户名密码进行认证,认证通过则生成TGC,同时生成TGT,TGC与TGT通过key-value形式关联起来,并通过TGT签发一个ST,然后将ST和TGC返回给浏览器,浏览器将TGC作为cookie保存起来,并将ST加入用户请求中,发给应用服务器。应用服务器拿到ST,然后传递给cas server进行验证该ST的合法性,验证通过则接受请求,开始处理业务逻辑。当后续的用户通过浏览器请求应用服务器时,就会直接携带TGC,应用服务器将浏览器重定向到cas server进行获取ST,cas server通过TGC和TGT的缓存对应,直接拿到TGT生成ST给浏览器,然后浏览器携带ST向应用服务器发起请求。

下面是基于redis数据库做的sso数据结构设计方案

数据结构设计

TGT对象(HASH类型)

属性:

代码语言:javascript
复制
{
    "expirationPolicy": "XXX",     // 二进制字符串
    "lastTimeUsed": "285335482",  // 上次使用时间
    "previousLastTimeUsed": "582852df",  // 上上次使用时间
    "creationTime": "234dfea",  // TGT创建时间
    "countOfUses": "2",   // 使用次数
    "parentTgtId": "TGT-XXX",    // 父TGT
    "expiredTime": "",   // 过期时间
    "services": "XXX",  // 跳转的url,二进制字符串
    "authentication": "XXX",  // 身份信息,二进制字符串
    "expired": "true",  // 是否已失效
    "loginURL": "{login-URL}", // 登录地址
}

User-TGT对象(SET类型)

ticket.userId:{user-id} 标识一个用户的在线会话 元素:

代码语言:javascript
复制
{
    "TGT-1",
    "TGT-2"
}

TGT对象(ZSET类型)

ticket.tgts: 所有TGT,按时间排序 元素:

代码语言:javascript
复制
{
    "TGT-1",
    "TGT-2"   
}

ST对象(HASH类型)

ticket.st:{ST-id} 属性:

代码语言:javascript
复制
{
    "expirationPolicy": "XXX",     // 二进制字符串
    "lastTimeUsed": "285335482",  // 上次使用时间
    "previousLastTimeUsed": "582852df",  // 上上次使用时间
    "creationTime": "234dfea",  // TGT创建时间
    "countOfUses": "2",   // 使用次数
    "parentTgtId": "TGT-XXX",    // 父TGT
    "expiredTime": "",   // 过期时间
    "services": "XXX",  // 跳转的url,二进制字符串
    "fromNewLogin": "true",  // 是否新的登录生成的
    "grantedTicketAlready": "true",  // 是否已有TGT关联
}

下面是redis的相关命令介绍

redis缓存

1、查看所有keys

代码语言:javascript
复制
30.1.3.29:26661> keys *
1) "ticket.st:ST-268-kuBYeNH1jarbho0d9yonUlnQ-sso"
2) "ticket.tgts:"
3) "ticket.tgtId_stId:6f6e776f021abd3858d288b6c150fde17523604cdfffc7e4618b8d7a95664fcd"
4) "ticket.userId:f4fe1232f30646ed84b397da39041e0f"
5) "global.users.login-records:f4fe1232f30646ed84b397da39041e0f"
6) "ticket.tgt:6f6e776f021abd3858d288b6c150fde17523604cdfffc7e4618b8d7a95664fcd"

如果keys提示不可用,则修改redis.conf配置文件:

代码语言:javascript
复制
rename-command FLUSHALL ""
rename-command EVAL ""
rename-command FLUSHDB ""
rename-command KEYS ""

去掉该keys重命名

2、查看类型

代码语言:javascript
复制
30.1.3.29:26661> type "ticket.st:ST-268-kuBYeNH1jarbho0d9yonUlnQ-sso"
hash

3、hash类型

查看hash类型的所有key
代码语言:javascript
复制
30.1.3.29:26661> hkeys "ticket.st:ST-268-kuBYeNH1jarbho0d9yonUlnQ-sso"
 1) "countOfUses"
 2) "creationTime"
 3) "lastTimeUsed"
 4) "fromNewLogin"
 5) "expiredTime"
 6) "services"
 7) "grantedTicketAlready"
 8) "expirationPolicy"
 9) "parentTgtId"
10) "previousLastTimeUsed"
查看过期时间
代码语言:javascript
复制
30.1.3.29:26661> ttl "ticket.st:ST-268-kuBYeNH1jarbho0d9yonUlnQ-sso"
(integer) 722
30.1.3.29:26661> 
30.1.3.29:26661> pttl "ticket.st:ST-268-kuBYeNH1jarbho0d9yonUlnQ-sso"
(integer) 709418

ttl为秒,pttl为毫秒

还有其他一些命令:hgetall keyhvals keyhget key field

4、有序集合zset

查看集合个数
代码语言:javascript
复制
30.1.3.29:26661> zcard "ticket.tgts:"
(integer) 1
获取所有元素
代码语言:javascript
复制
30.1.3.29:26661> zrange "ticket.tgts:" 0 -1
1) "6f6e776f021abd3858d288b6c150fde17523604cdfffc7e4618b8d7a95664fcd"
获取指定元素分数
代码语言:javascript
复制
30.1.3.29:26661> zscore "ticket.tgts:" 6f6e776f021abd3858d288b6c150fde17523604cdfffc7e4618b8d7a95664fcd
"1589460268224"

5、集合set

查看元素个数
代码语言:javascript
复制
30.1.3.29:26661> scard "ticket.userId:f4fe1232f30646ed84b397da39041e0f"
(integer) 1
查看所有元素
代码语言:javascript
复制
30.1.3.29:26661> smembers "ticket.userId:f4fe1232f30646ed84b397da39041e0f"
1) "6f6e776f021abd3858d288b6c150fde17523604cdfffc7e4618b8d7a95664fcd"
其他命令
  • 增加元素:sadd key member [member ...]
  • 随机获取元素:srandmember langs count
  • 判断元是否存在:sismember key member
  • 移除元素:srem key member [member ...]
  • 弹出元素:spop key [count]
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 有文化的技术人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 术语
  • CAS 基本原理
    • 结构体系
    • CAS 原理和协议
      • 基础模式
      • 数据结构设计
        • TGT对象(HASH类型)
          • User-TGT对象(SET类型)
            • TGT对象(ZSET类型)
              • ST对象(HASH类型)
              • redis缓存
                • 1、查看所有keys
                  • 2、查看类型
                    • 3、hash类型
                      • 4、有序集合zset
                        • 5、集合set
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档