资讯动态

CAS单点登录实战:从原理到部署,详解服务注册与跳转配置

发布时间:2026/8/16 21:13:44 来源:尧图企业网站定制
1. 项目概述从零构建企业级单点登录门户最近在帮一个中型技术团队做内部系统整合他们手上有七八个自研的管理后台、报表系统和运维平台每个系统一套独立的账号密码。新员工入职光记这些登录信息就得花半天更别提频繁切换带来的效率低下了。老板拍板要统一入口技术选型自然落到了CASCentral Authentication Service上。这玩意儿说白了就是一个“一次登录处处通行”的中央认证服务器是解决这类问题的标准方案。但真上手部署和配置尤其是搞定那个让人头疼的“登录成功跳转地址”你会发现官方文档虽然详尽却像一张没有重点的地图很多关键细节和实际生产中的“坑”都得自己踩一遍。这篇文章我就结合这次实战把CAS从部署、基础配置到最核心的登录跳转逻辑掰开揉碎了讲清楚。目标很明确让你能根据这篇指南独立部署一个稳定可用的CAS服务并深刻理解其背后的认证流程特别是服务注册与回调地址的配置这是整个系统能跑起来的关键。2. CAS核心架构与部署方案选型在动手敲命令之前我们必须先理解CAS到底是怎么工作的。它采用了一种经典的中心辐射型Hub-and-Spoke架构。想象一下CAS服务器就是机场的总安检口Hub而各个需要登录的应用如财务系统、CRM、OA就是不同的登机口Spoke。你只需要在总安检口CAS验一次票输入用户名密码拿到登机牌Ticket之后去任何一个登机口应用出示登机牌就能直接通行无需再次安检。2.1 认证流程拆解这个“出示登机牌”的过程在CAS协议里被标准化为以下几个步骤用户访问应用A用户浏览器试图访问一个受保护的应用Service。重定向至CAS应用A发现用户没有本地会话于是将用户重定向到CAS服务器的登录页面并在URL中携带自己的身份标识service参数。中央认证用户在CAS的登录页输入凭证用户名/密码。CAS服务器验证这些凭证的有效性。颁发票据Ticket验证成功后CAS生成一个一次性的、加密的票据——服务票据Service Ticket, ST并将用户浏览器重定向回最初的应用A同时在URL中附上这个ST。票据验证应用A的后台接收到这个ST它不会信任客户端传来的东西而是秘密地通过后端HTTPS调用向CAS服务器询问“这个ST有效吗是给谁用的”建立本地会话CAS服务器验证ST有效且是签发给应用A的则返回该ST对应的用户身份信息如用户名、属性。应用A据此在本地为用户创建会话Session之后用户在该应用内的访问就不再需要经过CAS了。整个流程的核心安全基石在于ST它是一次性的、绑定特定服务的并且验证过程发生在应用服务器与CAS服务器之间避免了在浏览器端被窃取的风险。2.2 部署方式深度对比理解了原理我们来看部署。CAS社区非常活跃提供了多种部署方式选择哪种取决于你的团队技术栈和运维习惯。方案一传统WAR包部署推荐新手入门这是最经典、文档最全的方式。你需要自己准备一个Servlet容器如Apache Tomcat然后将CAS项目编译打包成的WAR文件部署进去。它的优势是直观所有文件都在你眼皮底下调试方便。你可以清晰地看到WEB-INF下的配置文件和日志输出。但缺点也很明显需要自己管理Tomcat、配置HTTPS、处理会话持久化等运维成本稍高。方案二Spring Boot Overlay项目当前主流选择这是目前最推荐的方式尤其适合熟悉Spring Boot的团队。你不需要直接修改CAS庞大的源码而是创建一个自己的Maven或Gradle项目通过依赖cas-server-webapp等核心模块以“覆盖Overlay”的方式来自定义配置和UI。打包后生成的是一个可执行的JAR文件内嵌了Tomcat。这种方式极大简化了部署一条java -jar命令即可启动并且能轻松集成Spring Cloud Config做配置中心非常适合云原生环境。我们本次实战就采用此方案。方案三Docker容器化部署如果你所在团队已经全面容器化那么使用Docker或Kubernetes来部署CAS是自然之选。官方提供了Docker镜像你可以通过环境变量或挂载配置文件卷来定制。这种方式实现了基础设施即代码部署、伸缩、回滚都极其方便。但需要你对Docker和容器编排有足够了解并且要妥善处理容器内的证书、秘钥管理问题。注意无论选择哪种部署方式HTTPS是强制要求。CAS协议在设计上就要求所有通信特别是传输Ticket时必须使用TLS加密否则会存在严重的安全风险。在生产环境请务必使用由可信CA签发的证书或使用内部PKI体系颁发的证书。3. 基于Spring Boot Overlay的实战部署我们选择Spring Boot Overlay方案因为它平衡了灵活性和简便性。下面是从零开始的详细步骤。3.1 环境准备与项目初始化首先确保你的开发机器上安装了JDK 11或以上版本CAS 6.x要求以及Maven 3.6。生成Overlay项目最方便的方法是使用官方的初始模板。你可以通过Spring Initializr或直接使用CAS项目提供的脚本。这里我们用一个更直接的手动方式来理解其结构。# 创建一个新的项目目录 mkdir my-cas-server cd my-cas-server创建pom.xml这是项目的核心。你需要声明对CAS Web应用模块的依赖并配置Spring Boot Maven插件。?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.example/groupId artifactIdmy-cas-server/artifactId version1.0.0/version packagingjar/packaging properties cas.version6.6.9/cas.version !-- 使用当时最新的稳定版 -- /properties dependencies !-- CAS Server Web Application -- dependency groupIdorg.apereo.cas/groupId artifactIdcas-server-webapp/artifactId version${cas.version}/version typepom/type /dependency !-- 添加你需要的其他模块例如JDBC认证支持 -- dependency groupIdorg.apereo.cas/groupId artifactIdcas-server-support-jdbc/artifactId version${cas.version}/version /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId version2.7.x/version !-- 需与CAS内置Spring Boot版本匹配 -- /plugin /plugins /build /xml创建配置文件目录在src/main/resources下创建application.yml或application.properties。这是Spring Boot的标准配置文件CAS的所有自定义都将在这里进行。3.2 核心配置详解CAS的配置项繁多我们聚焦最关键的几项服务器设置、认证源和日志。application.yml基础配置server: port: 8443 ssl: enabled: true key-store: file:/path/to/your/keystore.jks # 你的JKS密钥库路径 key-store-password: changeit key-password: changeit cas: server: name: https://cas.example.com:8443 # CAS服务器对外的基础URL authn: # 示例使用静态用户列表进行测试生产环境请勿使用 accept: users: casuser::Mellon # 更常见的配置是JDBC连接你的用户数据库 jdbc: query[0]: url: jdbc:mysql://localhost:3306/casdb user: dbuser password: dbpassword sql: SELECT password FROM users WHERE username ? field-password: password password-encoder: type: NONE # 根据你的密码存储方式选择如BCRYPT, SHA-256等 # 服务注册表配置 - 这是控制“跳转地址”的核心 service-registry: core: init-from-json: true # 从JSON文件加载注册的服务 json: location: file:/etc/cas/services # 服务定义文件存放目录 logging: config: file:/etc/cas/config/log4j2.xml # 外部日志配置关于HTTPS证书的实操心得 对于开发和测试你可以用Java的keytool命令快速生成一个自签名证书。但记住自签名证书在浏览器访问时会报安全警告需要手动信任。生产环境必须替换为可信证书。将证书导入JKS文件后确保server.ssl.key-store路径指向正确且进程运行用户有读取权限。3.3 构建与运行配置完成后进入项目根目录执行Maven打包命令mvn clean package如果一切顺利你会在target目录下看到一个名为my-cas-server-1.0.0.jar的可执行JAR文件。运行它java -jar target/my-cas-server-1.0.0.jar或者为了在后台运行并输出日志nohup java -jar target/my-cas-server-1.0.0.jar cas.log 21 启动后访问https://localhost:8443/cas/login你应该能看到CAS的默认登录页面。用配置文件中静态用户casuser和密码Mellon即可登录。登录成功后你会看到一个简单的CAS欢迎页面提示你“登录成功但未指定要访问的服务”。这就是我们接下来要解决的核心问题如何让登录成功后自动跳转回我们最初想访问的那个应用4. 服务注册与登录跳转地址的深度解析“登录成功跳转地址”这个需求在CAS的语境下本质是服务Service的管理与验证。CAS不会允许用户跳转到任意一个网址它只信任那些预先在它那里“登记注册”过的应用。这个登记处就是“服务注册表Service Registry”。4.1 服务注册表的工作原理你可以把服务注册表想象成一个公司的访客白名单系统。每个想接入CAS单点登录的应用比如“财务系统”、“邮件系统”都必须先向CAS管理员提交申请将自己的信息主要是它的入口URL即service参数登记到白名单里。当用户带着这个应用的“介绍信”ST回来时CAS会去白名单里核对“嗯这个应用确实是我们公司的ST也是我刚刚开给他的没问题放行。”在CAS中服务注册信息通常保存在数据库如H2, MySQL或JSON/YAML文件中。上面配置中我们使用了init-from-json: true就是从JSON文件加载。4.2 定义你的第一个服务JSON方式在/etc/cas/services目录下目录需提前创建创建一个JSON文件文件名有严格格式要求{服务名}-{数字}.json。例如我们为内部管理系统创建一个服务定义文件MyInternalApp-10000001.json{ class: org.apereo.cas.services.RegexRegisteredService, serviceId: ^(https|http)://app-internal.example.com(:\\d)?/.*, name: MyInternalApp, id: 10000001, description: 内部运营管理系统, evaluationOrder: 1, logoutType: BACK_CHANNEL, attributeReleasePolicy: { class: org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy, allowedAttributes: [cn, mail, department] } }关键参数解析class: 必须为RegexRegisteredService表示使用正则表达式匹配服务ID。serviceId:这是整个跳转逻辑的命门它是一个正则表达式用于匹配应用发来的service参数值。上面的例子匹配所有以http://或https://开头域名为app-internal.example.com端口可选的URL。.*表示匹配该域名下的所有路径。务必确保这个正则能精确匹配到你应用的真实访问地址且不要过于宽泛如.*以免安全风险。id: 服务的唯一数字标识不能重复。evaluationOrder: 评估顺序数字越小优先级越高。当多个服务正则匹配同一个URL时取顺序最小的。attributeReleasePolicy: 定义CAS在验证ST成功后可以返回哪些用户属性如姓名、邮箱给应用。这是实现用户信息同步的关键。4.3 应用端集成与跳转测试服务在CAS端注册好后你的应用称为CAS Client需要集成CAS客户端库。以Spring Boot应用为例可以添加spring-security-cas依赖。应用端的关键配置application.yml# 应用自己的端口和地址 server: port: 8080 # CAS客户端配置 security: cas: server: host: https://cas.example.com:8443/cas # CAS服务器地址 service: host: http://app-internal.example.com:8080 # 本应用对外访问地址 # Spring Security配置 oauth2: client: registration: cas: provider: cas client-id: MyInternalApp # 与服务注册名对应非必须但建议 authorization-grant-type: authorization_code redirect-uri: {baseUrl}/login/oauth2/code/{registrationId}核心跳转流程验证用户首次访问http://app-internal.example.com:8080/secure/page。应用CAS Client的Security拦截器发现用户未认证将其重定向至https://cas.example.com:8443/cas/login?servicehttp://app-internal.example.com:8080/login/cas这个service参数的值就是应用端配置的security.cas.service.host加上一个固定的回调端点通常是/login/cas。用户在CAS页面登录。CAS验证成功后会做两件事校验service参数检查http://app-internal.example.com:8080/login/cas是否匹配某个已注册服务的serviceId正则我们配置的^(https|http)://app-internal.example.com(:\\d)?/.*。匹配成功生成并重定向生成一个唯一的ST然后将浏览器重定向回这个service地址并附上SThttp://app-internal.example.com:8080/login/cas?ticketST-1-xxxxxx应用在/login/cas这个端点接收到请求提取出ST然后在应用服务器后端向CAS的/cas/p3/serviceValidate接口发起一个HTTPS请求验证此ST的有效性。CAS验证ST有效返回该用户的身份标识如用户名casuser。应用根据返回的用户名在本地建立会话。至此单点登录完成用户被跳转回最初想访问的/secure/page。为什么跳转地址总不对—— 90%问题的根源在实际操作中跳转失败最常见的原因就是service参数不匹配。请对照检查协议、域名、端口应用发送的service参数URL必须与JSON文件中serviceId正则匹配的部分完全一致。http和https不能混localhost和127.0.0.1被视为不同带端口和不带端口也不同。编码问题service参数是一个URL本身需要经过URL编码。如果其中包含特殊字符如,必须正确编码。大多数客户端库会自动处理但如果你手动拼接URL务必注意。回调端点路径确保应用端配置的回调路径如/login/cas是真实存在且被客户端库处理的。5. 高级配置与生产环境考量基础跑通后我们需要关注一些生产级特性让CAS更健壮、更安全。5.1 代理认证与多层跳转有些场景下应用A如门户网站在通过CAS登录后需要代表用户去访问另一个也受CAS保护的后端服务B如数据API而用户对此无感知。这就需要代理认证Proxy Authentication。在CAS注册表中为应用A开启代理功能在它的JSON定义中设置proxyPolicy: { class: org.apereo.cas.services.RegexMatchingRegisteredServiceProxyPolicy, pattern: ^https://api-backend.example.com/.* }允许它代理指定模式的后端服务。应用A获取PGT应用A在验证ST时额外请求一个代理票据Proxy Granting Ticket, PGT。CAS会颁发一个PGT并将其关联到一个PGT回调URL应用A预先提供的一个HTTPS端点。应用A为后端服务B获取PT应用A使用PGT向CAS申请一个用于访问服务B的代理票据Proxy Ticket, PT。访问服务B应用A用这个PT去访问服务B服务B像验证普通ST一样向CAS验证此PT。这个过程实现了安全的服务间认证是构建微服务架构下统一认证的重要环节。5.2 会话管理与集群部署单机部署的CAS会话Session保存在内存中。一旦需要多实例部署以实现高可用就必须解决会话共享问题。方案使用Redis存储会话在application.yml中添加配置cas: ticket: registry: cleaner: enabled: true tgt: timeout: 28800 # TGT默认有效期8小时 st: timeout: 30 # ST默认有效期30秒 webflow: session: storage: true spring: session: store-type: redis redis: host: localhost port: 6379这样所有CAS实例都将Ticket和Web会话存储到中央Redis实现了无状态化可以方便地水平扩展。5.3 监控与日志生产系统离不开监控。CAS集成了Micrometer可以轻松对接Prometheus和Grafana。启用执行器端点在application.yml中配置management.endpoints.web.exposure.include: health,info,metrics,prometheus。访问/actuator/prometheus获取Prometheus格式的指标。关键指标关注cas_ticket_granting_tickets_createdTGT创建数、cas_service_tickets_createdST创建数、cas_ticket_registry_size票据库存量以及登录失败次数等。日志方面建议将log4j2.xml外置并配置按天滚动、区分不同级别DEBUG用于排查INFO和WARN用于监控和不同组件如org.apereo.cas的日志文件。6. 常见问题排查与调试技巧实录即使按照指南操作也难免遇到问题。下面是我在多次部署中积累的排查清单。6.1 登录后无法跳转停留在CAS欢迎页症状输入正确密码后没有跳回应用而是显示“You have successfully logged into CAS. You may now proceed to your intended application.”排查步骤检查service参数在CAS登录页查看浏览器地址栏。找到service后面的部分将其复制出来并URL解码。确认这个解码后的URL是否与你为应用注册的serviceId正则表达式完全匹配特别是协议、主机名、端口。检查服务注册文件确认JSON文件在正确目录文件名格式正确且CAS启动时日志没有报错解析该文件。可以尝试在serviceId中使用更宽松的正则如^https?://.*临时测试但生产环境务必收紧。检查CAS日志查看CAS的DEBUG级别日志搜索“RegisteredService”看CAS在处理登录请求时是否找到了匹配的服务。日志通常会打印出匹配到的服务详情或未匹配的原因。6.2 应用端验证Ticket时失败403 Invalid Ticket症状应用日志显示向CAS验证ST时返回“INVALID_TICKET”或“INVALID_SERVICE”。排查步骤确认ST一次性ST只能用一次。如果刷新页面导致应用再次用同一个ST去验证必定失败。这是正常现象。检查网络连通性确保应用服务器能通过网络访问到CAS服务器的/cas/p3/serviceValidate接口默认端口8443。在应用服务器上用curl或telnet测试。检查验证URL应用端构建的验证URL必须完全正确包括CAS的主机名、端口、路径/cas/p3/serviceValidate以及正确的service和ticket参数。检查时间同步CAS服务器和应用服务器的时间必须同步NTP如果时间差过大可能导致Ticket因过期而被判定无效。6.3 HTTPS证书问题症状应用端在后台验证ST时抛出SSLHandshakeException或CertificateException。解决开发环境如果CAS使用自签名证书你需要将CAS服务器的证书或根证书导入到应用服务器的JVM信任库cacerts中。keytool -import -trustcacerts -alias casserver -file /path/to/cas.crt -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit生产环境为CAS服务器申请并配置由公共或内部CA签发的可信证书一劳永逸。6.4 用户属性无法传递到应用症状登录成功了但应用拿不到用户的邮箱、部门等信息。排查服务注册定义检查该服务的JSON文件中attributeReleasePolicy下的allowedAttributes列表是否包含了你想释放的属性名如mail。认证源配置检查CAS的认证源如JDBC查询是否配置了正确返回这些属性。在JDBC配置中你的SQL查询需要SELECT username, email AS mail, dept AS department FROM users ...并通过field-*映射或属性映射器来定义。应用端接收检查CAS客户端库的配置确保它正确地从CAS验证响应中解析并提取这些属性。部署和调试CAS就像在组装一个精密的认证枢纽每一个环节都必须严丝合缝。最关键的serviceId匹配规则建议在开发初期先用一个宽松的正则进行连通性测试等整个流程跑通后再逐步收紧到精确匹配确保安全。日志是你的最佳拍档遇到问题时把org.apereo.cas的日志级别调到DEBUG或TRACE绝大部分问题的根源都会清晰呈现。最后别忘了在一切就绪后关闭不必要的调试日志并做好性能监控你的CAS门户就能稳定地支撑起整个企业的统一认证了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价