当前位置: 首页 > ai >正文

CAS单点登录架构详解

目录

  • 概述
  • 核心概念
    • TGC (Ticket Granting Cookie)
    • TGT (Ticket Granting Ticket)
    • ST (Service Ticket)
  • 架构设计
    • 整体架构
    • 存储架构
    • 安全机制
  • 工作流程
    • 完整登录时序
    • 流程步骤详解
  • 技术实现
    • 会话管理
    • 数据同步问题
    • 最佳实践
  • 参考资料

概述

CAS (Central Authentication Service) 是一个企业级单点登录解决方案,为多个应用系统提供统一的身份认证服务。通过CAS,用户只需要在认证中心登录一次,即可访问所有受保护的应用系统,无需重复登录。

核心特性

  • 单点登录:用户只需登录一次即可访问所有授权应用
  • 安全可靠:基于票据机制,确保认证过程的安全性
  • 集中管理:统一的用户认证和会话管理
  • 应用解耦:应用系统无需关心具体的认证逻辑

适用场景

  • 企业内部多个应用系统的统一登录
  • 微服务架构中的身份认证
  • 跨域应用的单点登录需求
  • 需要集中用户管理的复杂系统

核心概念

CAS采用基于票据的认证机制,通过三种不同类型的票据来实现安全可靠的单点登录功能。

TGC (Ticket Granting Cookie)

TGC是CAS会话的唯一标识符,是连接用户浏览器和CAS服务器的桥梁。

基本特性
  • 本质:CAS服务器session的唯一标识(sessionId)
  • 作用:作为TGT的key,用于查找对应的用户会话信息
  • 存储位置:以cookie形式保存在用户浏览器中
  • 域限制:只在CAS服务器域下有效(如:sso.company.com)
  • 传输方式:每个HTTP请求自动携带
技术实现
TGC → sessionId (key)
TGT → session content (value)
关系:TGC:TGT = key:value

TGT (Ticket Granting Ticket)

TGT是CAS为用户签发的登录凭证,是验证用户登录成功的核心票据。

存储机制

重要说明:TGT本身不是存储在cookie中,而是存储在CAS服务器端。

  • 服务器端存储:TGT存储在CAS服务器端,具体存储位置取决于配置
  • Cookie关联:通过TGC作为key来查找对应的TGT
  • 安全考虑:TGT包含敏感的用户信息,不能直接暴露在客户端
数据结构
// 浏览器Cookie中
TGC = "CASTGC-xxxx-yyyy-zzzz"  // 仅仅是一个sessionId// CAS服务器端
TGT = {user: "zhang_san",roles: ["admin", "user"],permissions: [...],expireTime: 1640995200,services: ["app1", "app2"]
}// 关联关系
服务器缓存[TGC]TGT对象
设计原理

为什么TGT不能存储在Cookie中?

  1. 安全性:TGT包含敏感的用户信息和权限数据
  2. 大小限制:Cookie有4KB大小限制,TGT数据可能超出限制
  3. 篡改风险:客户端存储容易被篡改,服务器端存储更安全
  4. 集中管理:服务器端存储便于统一管理和控制

ST (Service Ticket)

ST是用户访问特定服务时提供的服务票据,是CAS安全架构的核心组件。

核心作用

ST实际上是一个临时通行证,用于解决以下关键问题:

  1. 安全隔离:TGT只能在CAS服务器内部使用,不能直接传递给各个应用系统
  2. 服务授权:每个ST只对特定的服务有效,实现了服务级别的访问控制
  3. 防止重放攻击:一次性使用特性,防止票据被截获后重复使用
设计原理

为什么需要ST而不直接用TGT?

  • 如果直接传递TGT给应用系统,TGT可能被恶意应用窃取
  • TGT一旦泄露,攻击者可以访问用户的所有授权服务
  • ST将TGT的权限范围限制在单个服务内
TGT(全局权限) → ST(单服务权限) → 应用系统验证↓                    ↓不离开CAS服务器        可以安全传输
生命周期
  • 生成时机:用户访问服务时发现没有有效的本地会话
  • 获取流程:302重定向到CAS服务器获取ST
  • 使用方式:携带ST重定向回目标服务
  • 验证过程:应用系统将ST发送给CAS服务器验证
  • 销毁时机:验证完成后立即销毁,确保一次性使用
实际应用场景

假设用户要访问邮箱系统:

  1. 用户已通过CAS登录(拥有TGT)
  2. 访问邮箱系统时,CAS为邮箱系统专门生成ST-mail
  3. 邮箱系统收到ST-mail后,向CAS验证
  4. CAS确认ST-mail有效且是为邮箱系统生成的
  5. 邮箱系统获得用户身份信息,建立本地会话
  6. ST-mail被销毁,无法再次使用
票据关系对比
特性TGTST
作用范围全局,所有服务单个服务
存储位置CAS服务器内部URL参数传输
生命周期用户会话期间一次性使用
安全等级高,不离开CAS中,可传输但限制使用
用途证明用户身份授权访问特定服务

架构设计

整体架构

┌─────────────────────────────────────┐
│           CAS服务器                 │
│  ┌─────────────┐  ┌─────────────┐   │
│  │  认证模块   │  │  票据管理   │   │
│  └─────────────┘  └─────────────┘   │
│  ┌─────────────┐  ┌─────────────┐   │
│  │  会话管理   │  │  安全策略   │   │
│  └─────────────┘  └─────────────┘   │
└─────────────────────────────────────┘│├─────────────────────────┐│                         │
┌─────────────▼─────────────┐ ┌─────────▼─────────────┐
│        应用系统A           │ │        应用系统B       │
│   ┌─────────────────┐     │ │   ┌─────────────────┐ │
│   │  CAS客户端      │     │ │   │  CAS客户端      │ │
│   └─────────────────┘     │ │   └─────────────────┘ │
└───────────────────────────┘ └───────────────────────┘

存储架构

CAS系统采用多层存储架构,包括浏览器Cookie存储和多个服务器端Session存储。

完整存储架构
浏览器Cookie存储                     服务器端Session存储
─────────────────────────────────────────────────────────────────CAS域 (sso.company.com):            CAS服务器端:
├── TGC="CASTGC-xxxx-yyyy"          ├── 缓存[TGC] → TGT对象
└── 作用:全局登录状态标识            └── 包含:用户信息、权限、有效期应用A域 (mail.company.com):         应用A服务器端:
├── JSESSIONID="APP-A-session"      ├── 缓存[JSESSIONID] → ApplicationSession
└── 作用:邮箱系统本地会话标识         └── 包含:用户信息、应用数据、权限映射应用B域 (oa.company.com):          应用B服务器端:
├── JSESSIONID="APP-B-session"      ├── 缓存[JSESSIONID] → ApplicationSession
└── 作用:OA系统本地会话标识          └── 包含:用户信息、应用数据、权限映射
应用端会话管理

除了CAS域的TGC,每个应用系统也会在自己的域下维护独立的会话:

应用域Cookie的作用

  • 本质:应用系统自己的session cookie
  • 域名:存储在应用系统的域下(如:mail.company.com)
  • 内容:应用系统的本地会话标识
  • 目的:维护用户在该应用中的登录状态

应用服务端存储内容

// 应用服务端Session存储示例
ApplicationSession = {sessionId: "APP-A-session-id",           // 对应cookie中的值userId: "zhang_san",                     // 从CAS获取的用户身份userInfo: {                              // 从CAS获取的用户信息name: "张三",email: "zhangsan@company.com",roles: ["admin", "user"]},appSpecificData: {                       // 应用特定的会话数据currentPage: "/inbox",preferences: {...},businessContext: {...}},permissions: ["read_mail", "send_mail"], // 应用内权限loginTime: 1640995200,lastAccessTime: 1640995800,expireTime: 1640999400
}
存储关系对比
组件Cookie存储服务器端存储存储内容
CASTGC (sessionId)TGT对象用户身份、全局权限、有效期
应用AJSESSIONIDApplicationSession用户信息+应用特定数据
应用BJSESSIONIDApplicationSession用户信息+应用特定数据

安全机制

  1. 票据时效性:所有票据都有明确的有效期
  2. 一次性使用:ST只能使用一次,防止重放攻击
  3. HTTPS传输:所有敏感信息通过HTTPS传输
  4. 会话管理:完善的会话超时和清理机制
  5. 域隔离:不同域名的cookie自然隔离
  6. 权限分级:全局权限(TGT)和服务权限(ST)的分离

工作流程

完整登录时序

用户 → 应用系统(SP) → CAS服务器 → 应用系统(SP) → 用户│         │              │              │         ││    ①访问受保护资源      │              │         ││         │              │              │         ││    ②重定向到CAS        │              │         ││         │              │              │         ││    ③请求登录页面────────→              │         ││         │              │              │         ││    ④返回登录表单←────────              │         ││         │              │              │         ││    ⑤提交登录信息────────→              │         ││         │              │              │         ││    ⑥验证并生成TGT       │              │         ││         │              │              │         ││    ⑦返回ST并重定向──────→              │         ││         │              │              │         ││    ⑧验证ST请求─────────────────────────→         ││         │              │              │         ││    ⑨返回验证结果←──────────────────────         ││         │              │              │         ││    ⑩建立会话并访问──────────────────────────────→

流程步骤详解

1. 用户访问应用系统

用户通过浏览器访问受保护的应用系统(Service Provider, SP)。

2. SP检测未登录状态

SP检测到用户未登录,重定向用户到CAS服务器进行身份验证。

3. 用户请求登录页面

用户的浏览器向CAS服务器发送请求,请求登录页面。

4. CAS提供登录表单

CAS服务器响应,返回包含登录表单的HTML页面给用户。

5. 用户提交登录信息

用户在表单中输入用户名和密码,提交表单信息回CAS服务器。

6. CAS验证用户凭据

CAS服务器验证用户的用户名和密码。验证成功后:

  • 生成TGT(Ticket-Granting Ticket)
  • 将TGT存储在服务器的票据存储中
  • 将TGT对应的cookie(TGC)发送给用户浏览器
7. 重定向回SP并携带service ticket

用户浏览器被重定向回SP,URL中携带一个service ticket(ST)。ST是基于当前服务生成的,用于一次性使用。

8. SP验证service ticket

SP接收到ST后,向CAS服务器发送验证请求,包含ST以及SP自己的标识信息。

9. CAS验证service ticket有效性

CAS服务器验证ST的有效性(检查TGT和ST的一致性等),确认无误后,向SP返回验证结果,通常包含用户的身份信息或确认验证成功的标志。

10. SP建立用户会话

SP根据CAS的验证结果,为用户建立会话,允许用户访问受保护的资源。

11. 用户访问受保护资源

用户可以直接与SP交互,访问受保护的内容,直到会话结束或超时。

多应用访问流程

用户在完成首次登录后,访问其他应用的流程会更加简化:

  1. 首次访问应用A

    • 检查mail.company.com域下的cookie → 无会话
    • 重定向到CAS进行认证
  2. CAS认证成功

    • 在sso.company.com域下设置TGC
    • 生成ST重定向回应用A
  3. 应用A验证ST

    • 验证ST成功后,在mail.company.com域下设置自己的session cookie
    • 建立用户在应用A的本地会话
  4. 后续访问应用A

    • 直接检查mail.company.com域下的cookie
    • 有有效会话则直接访问,无需再次认证
  5. 访问应用B

    • 检查oa.company.com域下的cookie → 无会话
    • 重定向到CAS,CAS检查TGC → 已登录
    • 直接生成ST重定向回应用B(无需重新输入密码)

技术实现

会话管理

应用会话的特点

重要澄清:应用服务器的Session不是CAS的缓存,而是包含两部分数据:

  1. 从CAS获取的用户信息(一次性获取)
  2. 应用自己产生的业务数据(持续更新)
数据获取方式
// ST验证时,CAS返回的用户信息(一次性)
CASValidationResponse = {userId: "zhang_san",attributes: {name: "张三",email: "zhangsan@company.com", roles: ["admin", "user"]}
}// 应用服务器基于此信息创建自己的Session
ApplicationSession = {// 从CAS获取的用户信息(不变)userId: "zhang_san",userInfo: {...},// 应用自己产生的数据(持续变化)currentPage: "/inbox",           // 用户当前页面unreadCount: 5,                  // 未读消息数preferences: {...},              // 用户偏好设置businessContext: {...},          // 业务上下文lastOperation: "send_mail",      // 最后操作// 应用自己的会话管理loginTime: 1640995200,lastAccessTime: 1640995800,expireTime: 1640999400
}
应用与CAS的交互模式
应用服务器 ←→ CAS服务器的交互:
1. ST验证时:获取用户信息(一次性)
2. 单点登出时:通知会话失效(事件驱动)
3. 正常运行时:相互独立,无实时交互应用服务器内部的Session管理:
1. 基于CAS用户信息创建会话
2. 独立管理应用业务数据
3. 独立控制会话超时和清理

数据同步问题

同步延迟现象

如果用户在CAS中修改了信息(角色、权限、邮箱等),应用服务器不会立即知道这些变化。

问题原因
时间线:
T1: 用户通过ST验证,应用获得用户信息快照
T2: 用户在CAS中修改了角色(admin → user)
T3: 应用服务器仍然认为用户是admin
T4: 直到用户重新登录或会话超时,应用才会获得新信息
实际影响
// 场景:用户权限被管理员撤销
CAS系统:
用户角色: admin → user (已修改)应用服务器Session(仍是旧信息):
ApplicationSession = {userId: "zhang_san",roles: ["admin"],          // 旧信息!permissions: ["admin_all"] // 旧权限!
}// 结果:用户仍然可以执行admin操作
利弊分析

优点(设计考虑)

  • 性能优化:避免每次请求都查询CAS
  • 系统稳定:应用不依赖CAS的实时可用性
  • 网络效率:减少CAS服务器压力

缺点(安全风险)

  • 权限延迟:权限变更不能立即生效
  • 信息过期:用户信息可能过期
  • 安全隐患:被撤销权限的用户可能继续操作

最佳实践

1. 会话超时策略
// 设置较短的会话超时时间
ApplicationSession.expireTime = 30分钟; // 强制重新认证
2. 实时权限验证
// 关键操作时重新验证权限
if (criticalOperation) {// 向CAS或权限系统重新查询当前权限currentPermissions = permissionService.getCurrentPermissions(userId);
}
3. 消息推送机制
// CAS推送用户信息变更事件
@EventListener
public void onUserInfoChanged(UserInfoChangedEvent event) {// 更新或清除相关用户的SessionsessionManager.invalidateUserSessions(event.getUserId());
}
4. 定期同步机制
// 定期从CAS同步用户信息
@Scheduled(fixedRate = 300000) // 5分钟
public void syncUserInfoFromCAS() {// 批量同步活跃用户信息
}
5. 实施建议
  1. 敏感操作实时验证:重要操作前重新验证权限
  2. 合理的会话超时:平衡性能和安全性
  3. 监控和审计:记录权限变更和访问日志
  4. 分层权限设计:区分长期权限和临时权限
6. 票据管理
  • TGT的生命周期管理
  • ST的一次性使用控制
  • 票据的安全存储和检索
7. 会话同步
  • 多应用系统间的会话状态同步
  • 单点登出的实现
  • 会话超时处理
8. 安全考虑
  • 防止会话劫持
  • 票据伪造防护
  • 传输加密保护
9. 性能优化
  • 票据缓存策略
  • 数据库连接池管理
  • 负载均衡支持

参考资料

技术文档

  • CAS官方文档
  • CAS协议规范

实现案例

  • CAS登录原理和实现
  • CAS单点登录详解
  • CAS架构设计与实现

相关技术

  • Spring Security CAS集成
  • SAML vs CAS比较

本文档详细介绍了CAS单点登录的完整架构设计和实现要点,涵盖了从基础概念到技术实现的全过程。通过理解CAS的票据机制、存储架构和工作流程,可以更好地设计和实现企业级的单点登录解决方案。

http://www.xdnf.cn/news/15422.html

相关文章:

  • 从零构建鸿蒙应用:深度解析应用架构与项目结构
  • linux 内核: 遍历当前所有进程
  • AR眼镜:重塑医学教育,开启智能教学新时代
  • 图像修复:深度学习实现老照片划痕修复+老照片上色
  • 物联网系统中MQTT设备数据的保存方法
  • HC595串转并
  • CUDA 环境下 `libcuda.so` 缺失问题解决方案
  • linux网络编程之单reactor模型(二)
  • 僵尸进程Zombie Process
  • Java核心类库深度解析与实战:从字符串处理到计算器开发
  • 【Android】按钮的使用
  • Windows远程FX的编解码器性能优化
  • vscode 打开c++文件注释乱码
  • WPF,Winform,HTML5网页,哪个UI开发速度最快?
  • 智驾芯片软件分层测试
  • Element plus参考vben逻辑实现的描述列表组件封装实践
  • Spark Expression codegen
  • 利用DeepSeek为chdb命令行客户端添加输出重定向和执行SQL脚本功能
  • uniapp 微信小程序Vue3项目使用内置组件movable-area封装悬浮可拖拽按钮(拖拽结束时自动吸附到最近的屏幕边缘)
  • JDK1.8函数式编程实战(附日常工作案例,仅此一篇耐心看完彻底搞懂)
  • 力扣73:矩阵置零
  • redis红锁
  • 微信小程序开发-桌面端和移动端UI表现不一致问题记录
  • 自然语言指令驱动的工业机器人协同学习系统:大语言模型如何重塑智能体协作范式
  • Containerd容器技术详解
  • 拥抱 Spring Boot:开启 Java 后端开发的“快车道”
  • 2025阿里云黑洞恢复全指南:从应急响应到长效防御的实战方案
  • AJAX 开发中的注意点
  • C++ Qt插件开发样例
  • Python初学者笔记第十三期 -- (常用内置函数)