Single Sign-on
SSO是老生常谈的话题了,但部分同学对SSO可能掌握的也是云里雾里,一知半解。本次手撕公司的SSO原理,试图以一种简单、流畅的形式为你提供有用的SSO原理。
按照本人一贯行文风格,我们先说什么是SSO,为什么要提出SSO?
SSO: 在多个系统中,只需要登陆一次,就可以访问其他相互信任的应用系统,表现的实际场景:
-
企业部署多个website,形成产品套件或产品矩阵,而账号集中统一管理
-
用户一次登陆,即可畅通不同域名下web服务
今天我们主要讲不同顶域下SSO的实现,引出CAS原理,CAS传送门:
手绘原理
用户首次访问website1
① 用户访问website1,website1需要认证, 用户当前没有登陆
② website1给客户端返回302重定向响应, 客户端重定向到SSO服务页:www.sso-website.com?service=https://www.website1.com
# 临时跳转,建议传参false返回302临时重定向响应
context.Response.Redirect(ssoURL, false);
用户并没有登陆SSO系统,所以SSO系统会返回登陆界面
③ 用户在SSO登陆页输入账户/密码
④ 登陆成功,SSO会在客户端写入cookie for sso[官方叫CASTGT]并产生一个302重定向响应,客户端将重定向到原website1地址,该请求携带了SSO此次认证成功的ticket
http://www.website1.com?ticket=XXXX-OOOO-XXXX-OOOO
⑤ website1收到以上重定向请求,解析QueryString中的ticket, 向SSO做一次ticket验证; 验证通过向客户端写入本站的cookie for website1
⑥ 上面第5步,浏览器地址会显示:http://www.website1.com?ticket=XXXX-OOOO-XXXX-OOOO, 在本站验证通过之后,会再次重定向回业务首页:www.website1.com。
之后用户访问website2
① 用户访问website2,用户在website2域并没有认证;跳转回www.sso-website.com?service=https://www.website2.com
② SSO检测到该用户在SSO域下存在Cookie for sso, 认定该用户已经登陆,故跳转回website2, 如上也会携带认证ticket
③ 如上,website2收到 website2.com?ticket=XXXX-OOOO-XXXX-OOOO请求, 会做一次SSO验证; 验证成功,写入本站cookie for website2
重难点解读
① SSO认证成功,写入的cookie for sso, 是登陆到其他系统的关键
② website1收到SSO发起的重定向请求,解析出ticket=XXXX-OOOO-XXXX-OOOO, 为什么还要做一次SSO验证?
因为website1收到的带ticket请求,有可能是伪造, 所以在website1中需要去SSO验证一次。
③ 标准的CAS登陆流程有三次302客户端重定向, 分别由原站点website1启动2次和SSO启动一次
理论上流程由服务端重定向也是可以的 ?? 看官若发现有漏洞,可在评论区回复。
④ 退出SSO登陆, 要做两件事情:
- 向SSO发起api请求,请求SSO删除用户在SSO域下的认证cookie for sso
- 移除本站的cookie for website1
⑤ 每个website,至少需要如下sso配置
"SsoOptions": { "BaseAddress": "https://sso-cas.sso.com", // 基地址 "LoginPath": "/login", // sso登陆地址 "LogoutPath": "/api/logout", // 退出sso登陆的api地址 "ValidateTGTPath": "/api/validate", // 验证ticket的api地址 "UserInfoPath": "/api/v2/userinfo" // 从sso拿到登陆用户信息的api地址 },
That' all,这是自己对SSO登陆的一些理解, 本图文希望以流畅的思路记录SSO流程, 各位看官不要吃快餐,知其然更知其所以然很关键。