基于Cookie的SSO登录分析和实现
2015-11-05 16:40
253 查看
什么是SSO?
现在很多大的互联网公司都会有很多的应用,比如以下是淘宝网的截图:天猫 聚划算
头条等都是不同的应用,有的甚至采用完全不同的域名,但是所有在淘宝注册的用户都是使用的一套用户名和口令,如果在这些系统直接切换做不到登陆状态的同
步,体验是非常差的。再举个栗子,很多公司内部系统也有很多个,比如HR系统,财务系统,考勤系统等等,如果员工在一个系统登陆了,跳转到另外一个系统还
需要登陆,就会让人很不爽...
基于此,
SSO(Single Sign On)应运而生。当然,我们来现实这个需求的方法有很多种,使用Cookie是其中比较简单的方式,主要需要解决的问题是:
Cookie是不能跨域传递的,如何将一个域的
Cookie通知给其它应用(不在同一个域)?
so,如果你对
cookie机制不太熟悉,请先
cookie会设计成不能跨域等相关问题。
如何实现?
SSO有以下几种方式实现共享Cookie
当我们的子系统都在一个父级域名下时,我们可以将Cookie种在父域下,这样浏览器同域名下的Cookie则可以共享,这样可以通过Cookie加解密的算法获取用户SessionID,从而实现SSO。但是,后面我们发现这种方式有几种弊端:
a. 所有同域名的系统都能获取SessionID,易被修改且不安全;
b. 跨域无法使用。
ticket验证,我们目前采取的是这种方式
这种实现的SSO有以下几个步骤:a. 用户访问某个子系统,发现如果未登录,则引导用户跳转到SSO登录页面;
b. 判断SSO是否已经登录;
c. 如果已经登录,直接跳转到回调地址,并返回认证ticket;
d. 如果未登录,用户正确输入用户名/密码,认证通过跳转到回调地址,并返回认证ticket;
e. 子系统获取ticket,调用SSO获取用户uid等信息,成功后让用户登录。
前面已经说了,如何通过
Cookie来实现
SSO,主要是如何解决跨域问题。首先来谈谈
Set-Cookie中的
domain属性。
Cookie domain
为了让Http协议在一定程度上保持上下文,
server在响应的头部可以加入
Set-Cookie来写入一些数据到客户端,
Set-Cookie中的
domain字段用来表示这个
cookie所在的域。
栗子:
我们访问
www.cookieexm.com,如果
server在返回头部中加入了
Set-Cookie,如果不指定
domain,那么默认这个
cookie的域就是
www.cookieexm.com,也就是只有访问
www.cookieexm.com时客户端才会把这个
cookie返给服务端。
如果我们指定
domain为
.cookieexm.com,那么客户端在访问以下域名:
www.cookieexm.com www1.cookieexm.com a.cookieexm.com ***.cookieexm.com时都能够把
cookie返回。
所以,我们得出一条结论:客户端对cookie的domain的匹配是从结尾进行匹配的,有了这个基础,我们就可以实现我们的
SSO登陆了。
cookie中需要注意的
设置为http-only
涉及登录凭证(如票据或者用户名)应该加密
cookie不能存放隐私数据
具体方案
假设我们需要在如下子系统**.a1.a2 **.b1.b2 **.c1.c2间实现单点登录,首先我们需要一个专门用于单点登陆的认证系统(sso.s1.s2)。假设目前系统处于未登录状态,访问
www.a1.a2为例:
分别看一下每个步骤作用:
请求
www.a1.a2
www.a1.a2收到请求,检查是否携带登录的cookie,目前没有登陆过,那么重定向到sso认证中心
SSO提供登陆窗口,用户输入用户名 口令。SSO系统验证用户名和口令
这一步是关键,如果登录成功,首先把SSO系统的Cookie放到客户端;同时,将用户的认证信息传递通过重定向传递给业务方,注意,这个传递明显不能通过cookie来传递(不同域嘛),一般是通过加密的querystring。
业务方的验证系统收到sso认证信息,再进行认证
业务方认证通过之后,把认证结果的cookie写入到
.a1.a2,至此,
SSO认证完成
重定向到业务系统
www.a1.a2,由前面的结论可知,此时所有以
.a1.a2结尾的业务系统都可以使用这个认证之后的
cookie
response
说明:
业务认证系统不一定存在,有些不是太敏感的系统可以直接从
SSO Authorization重定向到业务系统,并把
SSO的认证信息带过去。
承接上文,此时,如果用户访问
www.b1.b2应用,如下图所示:
与访问
www.a1.a2不同的是我们在重定向到
SSO Authorization时已经不需要再去输入用户名,因为
sso.s1.s2此时已经存有
cookie,直接用
cookie验证。
以上,就是一个简单的基于
Cookie的登陆系统。
其中几个问题需要重点解决
如何高效存储大量临时性的信任数据如何防止信息传递过程被篡改
如何让SSO系统信任登录系统和免登系统
对于第一个问题,一般可以采用类似与memcached的分布式缓存的方案,既能提供可扩展数据量的机制,也能提供高效访问
对于第二个问题,一般采取数字签名的方法,要么通过数字证书签名,要么通过像md5的方式,这就需要SSO系统返回免登URL的时候对需验证的参数进行 md5加密,并带上token一起返回,最后需免登的系统进行验证信任关系的时候,需把这个token传给SSO系统,SSO系统通过对token的验证 就可以辨别信息是否被改过
对于最后一个问题,可以通过白名单来处理,说简单点只有在白名单上的系统才能请求生产信任关系,同理只有在白名单上的系统才能被免登录。
转载地址:http://www.jianshu.com/p/baa94d5f1673
相关文章推荐
- Unity3D 学习 创建简单的按钮、相应事件
- Kafka单机伪分布式安装
- 在AS中logcat的设置过滤信息图文教程
- 深入浅出RxJava三--响应式的好处
- 中高级sql语句
- ubuntu x64 debootstrap
- Java-URLConnection类详解
- linux mysql 优化
- 【转】探索式测试:基本概念
- LEETCODE-Invert Binary Tree
- Win7 chm文件用什么打开?chm文件打不开的解决方法
- java常用类库之大数字操作类
- 深入浅出RxJava(二:操作符)
- 9patch 9.png图片
- jstl中empty
- 转载---ajax简单三层实现登陆
- 使用 as 和 is 运算符安全地进行强制转换
- 【转】 测试职业思考:如何成为一名优秀的软件测试工程师
- Angularjs 自定义服务 provide 里 provider 方法 以及 factory、 service 方法以及 provider 供应商的概念
- 关于---内网IP和外网IP