CAS 6.2.x 单点登录
环境
- 系统:Windows 10 企业版 LTSC 1809
- 开发软件:Intellij IDEA 2020.1 (UltiMate Edition)
- Intellij IDEA 还需要安装 Lombok 插件
- Java:11.0.7 2020-04-14 TLS
- Tomcat:apache-tomcat-9.0.38
- Gradle: gradle-6.6.1
- CAS Server: 6.2.x
- CAS Client: 3.4.1
集成方式
使用官方推荐的 Overlay 方式,Overlay 方式只需下载 cas.war 包,然后只添加自己所需要的模块和配置,修改源码时,也只需要配置源码相同路径的代码,即可覆盖源码。这种方式减少了打包复杂度和打包效率,自定义代码在长期的迭代过程中出现未知,或者混乱的代码块,在升级 CAS 版本时也能够减少很大的工作量。
项目地址
- CAS Server: https://github.com/apereo/cas-overlay-template
- CAS Client: https://github.com/cas-projects/cas-sample-java-webapp
项目的 hosts 配置
127.0.0.1 cas.example.org
127.0.0.1 client1.example.org
127.0.0.1 client2.example.org
Step1 拉取项目
git clone https://github.com/cas-projects/cas-sample-java-webapp
git clone https://github.com/cas-projects/cas-sample-java-webapp cas-sample-java-webapp2
git clone -b 6.2 https://github.com/apereo/cas-overlay-template cas-server
Step2 导入项目到 IDEA 中
CAS Server 项目
这里 CAS Server 项目是 Gradle
导入后,等待构建完成后,右下角可以看到提示要启用 Lombok,点击启用即可
CAS Client 项目
这里 Client 项目是 Mavn 项目
Client 2 同上的方式导入到 IDEA 中
最终如下图三个项目
Step3 配置 Tomcat 容器
CAS Server 项目
如下图配置,为 Tomcat 添加 War 包,并修改项目 URL 前缀,
Client 项目
Client1
配置 Tomcat 同 CAS Server 一样,配置URL分别为 Client1 和 Client2
Client2
Step4 修改配置
CAS Server 配置修改
application.yml
cas:
server:
name: http://cas.example.org:8080
prefix: ${cas.server.name}/cas
authn:
accept:
# 登录账号,默认为 casuser::Mellon
users: admin::admin
service-registry:
# 是否重新读取 json
init-from-json: true
json:
# 服务注册时读取的 json 文件位置
location: file:E:\\26-cas\\cas-overlay-template\\etc\\cas\\services
tgc:
# Cookies 保存时,http 需要设置该值为false,否则无法保存Cookies成功
secure: false
项目结构如图下,1和2位置需要对应
添加 json 服务注册的支持的依赖
在 build.gradle 中,配置如图下
HTTPSandIMAPS-10000001.json
{
"@class": "org.apereo.cas.services.RegexRegisteredService",
"serviceId": "^(http|https|imaps)://.*",
"name": "HTTPS and IMAPS",
"id": 10000001,
"description": "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
"evaluationOrder": 10000
}
HTTPSandIMAPS-10000001.json 文件来自,如下图,使用 explodeWar 命令从 cas.war包中解压出,然后从build/cas-resources/servers/ 中复制出来,还可以使用 getResource 命令直接复制指定文件出来,这里提个醒,getResource 命令在 Windows 下还需手动修改下 gradle 脚本中拷贝文件时使用的路径分隔符。
拷贝出来后,ServicesId 像中添加 http 的支持
"serviceId": "^(http|https|imaps)://.*",
Client 配置
只需修改 webapp/WEB-INF/web.xml 中如下图5个位置的配置
client2,在下图中3,5中配置的url修改对应的地址即可,就不赘述了
如下图位置注释:
否则CAS server 端会有: <No multifactor authentication providers are available in the application context to satisfy [[mfa-duo]]>
Step5 编译打包运行
CAS Server
因为是 Overlay 的方式,修改配置文件还需要将配置文件打包进 War 包内,所以需要执行下面命令
gradlew.bat clean copyCasConfiguration build
gradlew 可以如下图方式,先直接用浏览器下载到本地,然后修改配置读取本地 gradle
编译打包后,运行如下
Client2 同理
Step6 抓包验证单点登录的过程
-
浏览器输入 http://client1.example.org:9081/client1 并回车进入
如下图,请求 client1 后会返回 302 ,并跳转到 cas server 的登录界面
image_20201003162159.png -
输入账号密码登录
- 请求 login 登录接口验证成功后返回302重定向到 client 携带这 ticket=ST-xxx 并且设置了 cookie (Set-Cookie)
-
client1 后端接到带有 ticket=ST-xxx 的请求,然后回去请求 cas.example.org 验证 这个 ST-xxx ,验证成功回返回 302 重定向回用户真正想访问的资源,如下图的标号5为验证ST的请求,6 为验证成功后重定向的地址并且,设置了 client1 的 Cookie
image_20201003162503.png
登录成功后最终 Chrome 浏览器内的Cookie 如下
- 输入 client2 地址
浏览器输入: http://client2.example.org:9082/client2/ 并回车,可以看到直接登录了
- client2 先重定向到 cas.example.org 并带上 Service
- 由于上面 Client1 登录了,并设置 cas.example.org 的 Cookie 这是请求登陆时就带上了这个 Cookie 如图中标号3
- cas.example.org 验证这个 Cookie 成功后,表示是登录状态,又返回 302 并带上服务的 ticket=ST-xxx 重定向 client2 如图标号4
-
如图标号5 client2 接收并到CAS 中验证该 ticket=ST-xxx ,验证成功后再 返回 302 ,将调转到最终的用户想访问的资源页面,如图标号6
image_20201003163856.png
问题
在上面验证中,可能会碰到 Cookie 无法保存的问题,导致进入 client2 时还是要登录,后面发现问题是 Chrome 80+版本中 secure 设置 false 则SameSite不能设置为 None。
如下图,F12 控制台查看请求,查为什么 Cookie 没有保存
解决方式
-
配置 same-site-policy=none|lax|strict Cookie 属性
image_20201003214132.png -
Chrome 忽略该问题的方式
如下图禁用该属性
image_20201003170303.png
参考
- 官方 Overlay 教程(需要梯子):https://apereo.github.io/cas/6.2.x/installation/WAR-Overlay-Installation.html
- JSON 服务注册配置:https://apereo.github.io/cas/6.2.x/services/JSON-Service-Management.html#json-service-registry
- Cookie 设置:https://apereo.github.io/cas/6.2.x/configuration/Configuration-Properties-Common.html#cookie-properties
- SameSite 问题:https://guangming.zjport.gov.cn/detail/govconsult/2020_3/9_3/202009031220_1.shtml
- 单点登录过程图:https://apereo.github.io/cas/6.2.x/protocol/CAS-Protocol.html