单点登录(SSO)的设计与实现
一、前言
1、SSO说明
SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。https://baike.baidu.com/item/SSO/3451380
例如访问在网易账号中心(http://reg.163.com/ )登录之后
访问以下站点都是登录状态
- 网易直播 http://v.163.com
- 网易博客 http://blog.163.com
- 网易花田 http://love.163.com
- 网易考拉 https://www.kaola.com
- 网易Lofter http://www.lofter.com
2、设计目标
本篇文章也主要是为了探讨如何设计&实现一个SSO系统
以下为需要实现的核心功能:
- 单点登录
- 单点登出
- 支持跨域单点登录
- 支持跨域单点登出
二、SSO设计与实现
1、核心应用与依赖

| 应用/模块/对象 | 说明 |
|---|---|
| 前台站点 | 需要登录的站点 |
| SSO站点-登录 | 提供登录的页面 |
| SSO站点-登出 | 提供注销登录的入口 |
| SSO服务-登录 | 提供登录服务 |
| SSO服务-登录状态 | 提供登录状态校验/登录信息查询的服务 |
| SSO服务-登出 | 提供用户注销登录的服务 |
| 数据库 | 存储用户账户信息 |
| 缓存 | 存储用户的登录信息,通常使用Redis |
2、用户登录状态的存储与校验
常见的Web框架对于Session的实现都是生成一个SessionId存储在浏览器Cookie中。然后将Session内容存储在服务器端内存中,这个 ken.io 在之前Session工作原理中也提到过。整体也是借鉴这个思路。
用户登录成功之后,生成AuthToken交给客户端保存。如果是浏览器,就保存在Cookie中。如果是手机App就保存在App本地缓存中。本篇主要探讨基于Web站点的SSO。
用户在浏览需要登录的页面时,客户端将AuthToken提交给SSO服务校验登录状态/获取用户登录信息
对于登录信息的存储,建议采用Redis,使用Redis集群来存储登录信息,既可以保证高可用,又可以线性扩充。同时也可以让SSO服务满足负载均衡/可伸缩的需求。
| 对象 | 说明 |
|---|---|
| AuthToken | 直接使用UUID/GUID即可,如果有验证AuthToken合法性需求,可以将UserName+时间戳加密生成,服务端解密之后验证合法性 |
| 登录信息 | 通常是将UserId,UserName缓存起来 |
3、用户登录/登录校验
- 登录时序图

按照上图,用户登录后Authtoken保存在Cookie中。 domian= test. com
浏览器会将domain设置成 .test.com,
这样访问所有*.test.com的web站点,都会将Authtoken携带到服务器端。
然后通过SSO服务,完成对用户状态的校验/用户登录信息的获取
- 登录信息获取/登录状态校验

4、用户登出
用户登出时要做的事情很简单:
- 服务端清除缓存(Redis)中的登录状态
- 客户端清除存储的AuthToken
- 登出时序图

5、跨域登录、登出
前面提到过,核心思路是客户端存储AuthToken,服务器端通过Redis存储登录信息。由于客户端是将AuthToken存储在Cookie中的。所以跨域要解决的问题,就是如何解决Cookie的跨域读写问题。
解决跨域的核心思路就是:
登录完成之后通过回调的方式,将AuthToken传递给主域名之外的站点,该站点自行将AuthToken保存在当前域下的Cookie中。
登出完成之后通过回调的方式,调用非主域名站点的登出页面,完成设置Cookie中的AuthToken过期的操作。
跨域登录(主域名已登录)

跨域登录(主域名未登录)

跨域登出

三、备注
- 关于方案
这次设计方案更多是提供实现思路。如果涉及到APP用户登录等情况,在访问SSO服务时,增加对APP的签名验证就好了。当然,如果有无线网关,验证签名不是问题。
- 关于时序图
时序图中并没有包含所有场景,ken.io只列举了核心/主要场景,另外对于一些不影响理解思路的消息能省就省了。
作者:ken.io
链接:SSO 单点登录看这篇就够了!
来源:github
单点登录(SSO)的设计与实现的更多相关文章
- 单点登录(一)-----理论-----单点登录SSO的介绍和CAS+选型
什么是单点登录(SSO) 单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无须多次登录. 单点登录(Single Sign On),简称为 ...
- [转]单点登录SSO学习——CAS协议内容
作者:anmaler 本文转自:http://blog.zhaojunling.me/p/24 CAS中文文档甚少,这篇文章对CAS接口参数有比较清楚的说明,排版也不错查阅舒适 在当前互联网产品中使用 ...
- cas单点登录 SSO 的实现原理
原文出处: cutesource 欢迎分享原创到伯乐头条 单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户 ...
- 单点登录 SSO 的实现原理
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任. 单点登录在大型网站里使用 ...
- Atitit. 单点登录sso 的解决方案 总结
Atitit. 单点登录sso 的解决方案 总结 1. 系统应用场景and SSO模式选型 2 2. 系统应用的原则与要求 2 2.1. 开发快速简单::绝大部分系统来说,开发快速简单为主 2 2. ...
- 十六、【适合中小企业的.Net轻量级开源框架】EnterpriseFrameWork框架核心类库之单点登录SSO
回<[开源]EnterpriseFrameWork框架系列文章索引> EFW框架源代码下载:http://pan.baidu.com/s/1qWJjo3U 单点登录(Single Sign ...
- 单点登录SSO的实现原理
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得 ...
- 单点登录SSO原理
最近接触了一点单点登录的知识,有一点理解,记录一下.有些问题并没有找到完美的解决方法,还需要找点已有框架来看看. 欢迎留言探讨. 1 概念 1.1 概念及理解 有一个网上广为流传的 ...
- CAS单点登录(SSO)完整教程
转:http://blog.csdn.net/frinder/article/details/7969925 CAS单点登录(SSO)完整教程(2012-02-01更新) 一.教程说明 前言 教程目的 ...
- Redis缓存实现单点登录SSO
.NET基于Redis缓存实现单点登录SSO的解决方案 .NET基于Redis缓存实现单点登录SSO的解决方案 一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单 ...
随机推荐
- js对比两个时间的大小
/** * 时间对比 开始=结束返回0;开始>结束返回-1;开始<结束返回1 */ function dateComparison(date1,date2){ var start =new ...
- [leetcode]103. Binary Tree Zigzag Level Order Traversal二叉树Z字形层序遍历
相对于102题,稍微改变下方法就行 迭代方法: 在102题的基础上,加上一个变量来判断是不是需要反转 反转的话,当前list在for循环结束后用collection的反转方法就可以实现反转 递归方法: ...
- Qt学习笔记-界面设置入门
首先我们看的是qt类表.相当于是一个族谱.这个文档可以在网上搜到. 首先第一个是QObjiect. 然后是QWidget => 相当于是windowsget缩写. 同理: QColorDialo ...
- JavaDailyReports10_07
动手动脑① 1 package test_1; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 // TO ...
- Java学习日报8.5
package student;import java.util.*;public class student { Scanner sc=new Scanner(System.in); private ...
- 零基础学习python
一.python的注释方式: (1)python的单行注释: ctrl+/ # print('Hello World!') 这是当行注释 (2)python的多行注释: ''' ''' ' ' ' ...
- 通过BulkLoad快速将海量数据导入到Hbase(TDH,kerberos认证)
一.概念 使用BlukLoad方式利用Hbase的数据信息是 按照特点格式存储在HDFS里的特性,直接在HDFS中生成持久化的Hfile数据格式文件,然后完成巨量数据快速入库的操作,配合MapRedu ...
- EF Core CodeFirst数据库自动迁移
开发过程中都会遇到数据库数据结构更新的问题,怎么对数据库更新进行版本控制呢? 不同的项目对数据库版本更新控制的方式不同,常用的有第三方Evolve,开发人员将数据库更新脚本按照版本号的放在一起,然后执 ...
- 杭电OJ----1097:一个难题(c++)
问题描述 lcy给feng5166,lwg,JGShining和Ignatius带来了一个难题:给了a和b,如何知道a ^ b.每个人都反对这个BT问题,所以lcy使问题比开始容易. 这个难题描述了: ...
- [leetcode] 周赛 223
比赛题目:https://leetcode-cn.com/contest/weekly-contest-223/. 解码异或后的数组 题目:1720. 解码异或后的数组. 还记得数列求和的「累加法」? ...