一次偶然机会 ,工作中参与Single Sign On Role Player活动,还被选中要拍摄一个短视频来demo一下有关用户登录的三种不同场景,也就有必要来了解一下有关SSO的知识。
提要
- SSO 概念
- 普通访问认证机制
- 同域下的SSO
- 不同域下的SSO
- 总结
- 参考
SSO概念
Single Sign On简称SSO,也叫单点登录,是一种控制多个相关但彼此独立的系统的访问权限, 拥有这一权限的用户可以使用单一的ID和密码访问某个或多个系统从而避免使用不同的用户名或密码,或者通过某种配置无缝地登录每个系统 。也就是只需要登录一次,就可以访问其他相互信任的应用系统。
普通访问认证机制
- User 想要访问App的资源,发出请求资源
- App接收到请求,检查User请求没有带Cookie,说明User未登录,App redirect到login page,让User登录。
- User 输入登录信息完成login操作
- App记录User的login信息,存到数据库,生成一个sessionID,表明User已登录状态,将SessionID以cookie的形式返回给User, 浏览器将这个cookie记录到本地。
- User向App再发出请求资源,并带上Cookie
- App接到请求,并检查Cookie,在数据库里查找到对应的sessionID,说明用户已经是登录状态,验证通过,给用户返回资源。
- 用户得到资源,退出App
同域下的SSO
一个企业一般只有一个域名,通过二级域名区分不同的系统。比如我们有个域名叫做:a.com,同时有两个业务系统分别为:app1.a.com和app2.a.com。我们要做单点登录(SSO),需要一个登录系统,叫做:sso.a.com。
这里有两个问题:
Cookie是不能跨域的,我们Cookie的domain属性是sso.a.com,在给app1.a.com和app2.a.com发送请求是带不上的。
sso、app1和app2是不同的应用,它们的session存在自己的应用内,是不共享的。
针对第一个问题,sso登录以后,可以将Cookie的域设置为顶域,即.a.com,这样所有子域的系统都可以访问到顶域的Cookie。我们在设置Cookie时,只能设置顶域和自己的域,不能设置其他的域。
比如:我们不能在自己的系统中给baidu.com的域设置Cookie。
我们再来看看session的问题。我们在sso系统登录了,这时再访问app1,Cookie也带到了app1的服务端(Server),app1的服务端怎么找到这个Cookie对应的Session呢?这里就要把3个系统的Session共享
- User访问App1,App1进行验证,验证失败,跳转至SSO,要求User登录;
- User通过SSO登录,SSO进行验证,成功并生成SessionID,随后将UserInfo( SessionID、ID和口令)存储到Common Session中,跳转至App1(携带SessionID),并允许User访问App1;
- User保存UserInfo ( SessionID ) 至 cookie,
将Cookie的域设置为顶域,即.a.com
; - User 再访问 App2 ( 并携带 在3 中保存至cookie 中的 UserInfo ) ,App2从Common Session中拉取UserInfo 进行验证,成功则允许访问;
不同域的SSO
同域下的单点登录是巧用了Cookie顶域的特性。如果是不同域呢?不同域之间Cookie是不共享的,怎么办?
这里我们就要说一说CAS流程了,这个流程是单点登录的标准流程,我们将CAS统一为SSO系统。
前提:
App注册, App1和App2向SSO请求注册,带个App信息(如URL等等,SSO分别存储App信息并返回App1 token, App2 Token信息。
- User访问App1
- App1检测到User没有登录(未带cookie信息),redirect User to SSO,并附上自己的encoded URL
- User带上App1的URL向SSO请求访问
- SSO检测到User未登录(未带cookie信息),App1有注册过,合法应用,redirect User to login page
- User输入登录信息,SSO存储User 信息,并生成login token,并根据App1的URL生成一个App1的Access Token,将login token以cookie形式,App1 Access Token以query parameter形式,redirect User to App1
- User(Browser)将login access存到本地cookie,User带上App1 Access Token再次访问App1
- App1带上App1 Access Token和自己的URL向SSO发起验证。
- SSO验证App1 Access Token通过
- App1收到SSO验证通过,生成并存储一个User Access App1 Session,将Uer redirect to resource page,设置cookie为User Access App1 Session
- User(Browser)记录User Access App1 cookie,并带上这个cookie访问App1的资源
10.App1 验证User Access App 1 Cookie通过,返回资源给User
只要User Acess App1 Cookie有效期内,User都可以直接访问App1的资源了。
接下来User访问App2:
- User访问App2
- App2检查到User未登录(未带上Cookie信息),redirect User to SSO,并附上自己的encoded URL
- User带上之前存的sso的Cookie,App2的URL信息访问SSO
- SSO验证Cookie找到存储中对应的Session ID,说明用户登录了,并根据App2的URL验证App2是注册过的,于是生成一个App2 Access Token,并将App2 Access Token以query parameter的形式将User redirect to App2
- User带上App2 Access Token再次访问App2
- App2和SSO发出验证App2 Access Token请求
- SSO验证通过
- App2收到SSO验证通过,生成并存储一个User Access App2 Session,将Uer redirect to resource page,设置cookie为User Access App2 Session
- User(Browser)记录User Access App2 cookie,并带上这个cookie访问App2的资源
- App2 验证User Access App2 Cookie通过,返回资源给User
只要User Acess App2 Cookie有效期内,User都可以直接访问App2的资源了。
总结
总结一下单点登录要做的事情:
单点登录(SSO系统)是保障各业务系统的用户资源的安全 。
各个业务系统获得的信息是,这个用户能不能访问我的资源。
单点登录,资源都在各个业务系统这边,不在SSO那一方。 用户在给SSO服务器提供了用户名密码后,作为业务系统并不知道这件事。 SSO随便给业务系统一个Access Token,那么业务系统是不能确定这个Access Token是用户伪造的,还是真的有效,所以要拿着这个Access Token去SSO服务器再问一下,这个用户给我的ST是否有效,是有效的我才能让这个用户访问。
参考
https://www.cnblogs.com/EzrealLiu/p/5559255.html
https://www.jianshu.com/p/75edcc05acfd