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.pswp.cn/bicheng/89078.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89078.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++中正则表达式详解和实战示例

C 中的正则表达式&#xff08;Regular Expression&#xff09;主要通过标准库 <regex> 提供&#xff0c;能够用于字符串匹配、查找、替换、验证格式等。它在 C11 中首次引入&#xff0c;并在 C14 和 C17 中逐步完善。一、头文件和命名空间 #include <regex> #inclu…

深入解析Avro、Protobuf与JSON:序列化技术的选择与应用

在现代分布式系统和数据交换场景中&#xff0c;序列化技术是数据存储、传输和通信的核心。本文深入探讨三种主流序列化技术&#xff1a;Avro、Protobuf 和 JSON&#xff0c;从背景、特点、示例代码&#xff08;Python&#xff09;、优势及最佳实践等多个维度进行对比分析&#…

Vue 中 effectScope() 的全面解析与实战应用

一、effectScope 概述1.1 什么是 effectScopeeffectScope() 是 Vue 3.2 引入的核心 API&#xff0c;用于创建副作用作用域容器。它能够将多个响应式副作用&#xff08;如 watch、watchEffect 和 computed&#xff09;组织在一起&#xff0c;实现统一的生命周期管理。1.2 核心价…

嵌入式面试八股文(十六)·一文搞懂嵌入式常用名词IC、ASIC、CPU、MPU、MCU、SoC、SoPC、GPU、DSP

目录 1. IC&#xff08;Integrated Circuit&#xff0c;集成电路&#xff09; 2. ASIC&#xff08;Application-Specific Integrated Circuit&#xff0c;专用集成电路&#xff09; 3. CPU&#xff08;Central Processing Unit&#xff0c;中央处理器&#xff09; 4. M…

安全参綉25暑假第一次作业

第一天 1.首先讲了d0cker的部署&#xff0c; 这个是第一个Vulhub漏洞环境。所有环境都使用D0cker容器化&#xff0c;使其易于部署和隔离测试。 其中&#xff0c;国内的阿里用不了&#xff0c;你得搞个代理&#xff0c;下国外的&#xff1a;入门指南 | Vulhub 然后按这个…

RocketMQ源码级实现原理-消息消费总览

Overview可以看到&#xff0c;pull message和consume message实际上是两个过程&#xff0c;但是对于用户是透明的 注意这三个Offset的含义&#xff0c;physical offset就是commitLog中的全局偏移量分发dispatch如上图&#xff0c;Topic的每个queue&#xff0c;都绑定了唯一的一…

linux打包固件shell脚本

不打包 pack.sh解压后无父目录&#xff08;直接是文件&#xff09;生成 checksum.txt&#xff08;包含所有文件的 SHA256&#xff09;打包后 .tar.gz 移动到上级目录#!/bin/bash# 检查是否传入版本号参数 if [ -z "$1" ]; thenecho "Usage: $0 <version> …

用uniapp开发鸿蒙应用(暂停更新-根据项目更新,现在项目未开始)

1.根据博客生成.hap文件 【鸿蒙HarmonyOS开发技巧&#xff1a;如何不依赖华为商店直接安装uniapp生成的app文件&#xff1f;一键转换app至hap格式教程详解】_entry-default-signed.hap-CSDN博客 根据网络查询鸿蒙手机安装测试app&#xff0c;需要电脑命令安装 在鸿蒙HarmonyOS手…

Linux 文件系统实现层详解:原理、结构与驱动衔接

&#x1f4c2; Linux 文件系统实现层详解&#xff1a;原理、结构与驱动衔接 &#x1f3ac; 推荐搭配视频学习&#xff1a;Linux 文件系统子系统&#xff1a;三层架构全面掌握 一、为什么要重点理解文件系统实现层&#xff1f; 文件系统实现层是 Linux 文件系统的“地基”&…

区块链应用场景深度解读:金融领域的革新与突破

引言&#xff1a;区块链技术的演进与金融领域的变革区块链技术自2008年诞生以来&#xff0c;以其去中心化、不可篡改、可追溯等特性&#xff0c;在全球范围内引发了金融领域的深刻变革。从最初的数字货币实验&#xff0c;到如今在跨境支付、证券交易、供应链金融等领域的广泛应…

redisson tryLock

应用场景RLock rLock redissonClient.getLock(Constant_LOCK request.getId()); try {boolean isLocked rLock.tryLock();if (!isLocked) {throw new ServiceException(ErrConstant.OPERATION_FAILED, "请勿重复提交");}源码public interface RLock extends Lock,…

前端docx库实现将html页面导出word

前言&#xff1a;最近遇到一个需求&#xff0c;需要将页面的html导出为word文档&#xff0c;并且包含横向和竖向页面&#xff0c;并且可以进行混合方向导出。经过一段时间的实验&#xff0c;发现只有docx这个库满足这个要求。在这里记录一下实现思路以及代码。 docx官网 一、…

虚拟主机CPU占用100导致打不开的一次处理

背景 突然有一天&#xff0c;有个客户网站打不开了&#xff0c;发来这样一张图片问题排查 打开阿里云虚拟主机控制面板&#xff0c;CPU 使用率已经达到了100%&#xff0c;这说明网站已经在高负荷运转。分析访问日志发现&#xff0c;网站出现了大量循环路径&#xff0c;其 UserA…

设计模式之工厂模式:对象创建的智慧之道

工厂模式&#xff1a;对象创建的智慧之道 引言&#xff1a;为什么我们需要工厂模式&#xff1f; 在软件开发中&#xff0c;对象创建是最常见的操作之一。当代码中充满new关键字时&#xff0c;系统会面临三大痛点&#xff1a; 紧耦合&#xff1a;客户端代码直接依赖具体实现类扩…

Docker镜像制作案例

1、使用Docker commit制作镜像为ubuntu镜像提供ssh服务①&#xff1a;拉取镜像[rootopenEuler-1 ~]# docker pull ubuntu:18.04②&#xff1a;启动镜像[rootopenEuler-1 ~]# docker run --name c1 -it --rm ubuntu:18.04 bash③&#xff1a;替换aliyun源mv /etc/apt/sources.li…

KeilMDK5如何生成.bin文件

1&#xff1a;主要是要找到fromelf.exe的路径2&#xff1a;接下来要做的要视情况而定&#xff1a;选完fromelf.exe后在输入框中加个空格然后加一串字 : --bin -o ./Obj/L.bin ./Obj/L.axf&#xff0c;如下我设置的L最终会替换成项目名 3&#xff1a;去构建生成编译一下&#…

Ajax接收java后端传递的json对象包含长整型被截断导致丢失精度的解决方案

问题描述 在使用java编写代码的时候,后端返回前端的JSON对象中包含了Long长整型,前端接受的时候丢失了精度问题。 比如: 后端传递的json {"code": "200","msg": "操作成功","data":

MybatisPlus由浅入深

MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&#xff0c;旨在简化开发过程。基本使用步骤1.依赖引入<!-- mysql依赖 --> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>…

蓝牙信号强度(RSSI)与链路质量(LQI)的测量与应用:面试高频考点与真题解析

在蓝牙通信领域&#xff0c;信号强度&#xff08;RSSI&#xff09;和链路质量&#xff08;LQI&#xff09;是评估无线链路性能的核心指标。无论是智能家居设备的连接优化&#xff0c;还是工业物联网中的抗干扰设计&#xff0c;这两个指标都扮演着关键角色。本文将结合面试高频考…

PyTorch的计算图是什么?为什么绘图前要detach?

在PyTorch中&#xff0c;计算图&#xff08;Computational Graph&#xff09; 是自动求导&#xff08;Autograd&#xff09;的核心机制。理解计算图有助于解释为什么在绘图前需要使用 .detach() 方法分离张量。一、什么是计算图&#xff1f; 计算图是一种有向无环图&#xff08…