SSO, Single Sign On, 单点登录
1. 应用场景
大型Web项目一般都有这样的开发场景:
- 项目子系统众多, 需要一个统一的登录系统, 用户只需要登录一次就可以访问其他信任的子系统应用.
- 子系统间依赖复杂, 前端页面间有相互跳转需求.
- 前后端分离, 各个系统间需要跨域访问.
2. 单点登录序列图
ticket
SSO系统发放给前端页面的登录凭证, 之后交给子系统判断其有效性.
为了防止被拦截, ticket的存活时间极短, 一般设置为5秒左右.sid
即Session ID, 用户登录成功后的会话ID.
同一用户在各个系统间获得的sid应该不同, 以防止某个子系统泄露sid而影响其他子系统.
用户与sid之间是一对多的关系.
- 用户在浏览器触发任意请求访问子系统.
- 子系统验证请求的Cookie中是否有sid.
假设目前为首次登录, Cookie为空, 则返回未登录状态. - 子系统页面跳转到SSO系统的登录页面.
- 用户输入相关登录信息(用户名, 密码, 验证码等), 请求登录验证.
- SSO系统验证用户信息, 生成ticket及用户信息;返回结果中将sid写入Cookie, 用于免登, 防止用户重复登录.
- 浏览器跳转到回调页面, 该页面用于统一验证ticket, 可设计成空白页面.
若不用回调页面, 则需要每个页面都有处理ticket的能力. - 浏览器向子系统请求验证ticket.
- 子系统向SSO系统请求验证ticket.
- SSO系统验证完成后销毁ticket, 并为子系统生成sid.
该sid与之前步骤5的sid不同, 原因之前已说明. - 子系统缓存用户相关信息, 返回登录状态.
- 浏览器重新跳转到原url, 触发任意请求.
- 子系统验证Cookie中是否sid.
若之前步骤都成功, 则此时Cookie一定带有sid. - 子系统从本地缓存中获取用户信息.
用户信息缓存时间不宜过长, 避免用户长时间不操作或不友好退出后, 占用缓存空间资源.
若无缓存信息, 则向SSO系统获取. - 子系统向SSO系统获取用户权限列表.
此步骤也可做缓存处理, 同样缓存时间也不宜过长. - SSO系统查询并返回用户权限列表.
- 子系统正常处理请求并返回处理结果.
3. 缓存内容
sid --n–1--> userid, loginTime, SubModuleID
userid --1–1--> userInfo, permissionList
4. 安全问题
- ticket与sid应使用uuid类型的字符串, 防止暴力破解
- 为了防止被拦截, ticket的存活时间极短, 一般设置为5秒左右.
- 同一用户在各个系统间获得的sid应该不同, 以防止某个子系统泄露sid而影响其他子系统.
- 缓存设置时间不宜过长, 一方面避免占用空间资源, 另一方面防止回话被劫持.可以用户触发接口后延期, 但到一定时间后必须销毁.
- 在修改用户重要信息或权限后, 自动登出.
- CSRF攻击
- XSS攻击
- 日志记录用户操作, 无论成功还是失败, 防御各种攻击.
5. 性能问题
- 缓存时间过不宜过短, 防止接口频繁调用, 缓存频繁写入.
6. 迭代开发
迭代开发BOSS系统, 在统一的系统页面可以管理所有子系统, 不用在不同的系统中跳转, 方便运维.