SSO 单点登录(转发)(待续)

原文:https://blog.csdn.net/mccand1234/article/details/81268524

简介

SSO英文全称Single Sign On
单点登录是一种控制多个相关但彼此独立的系统访问权限的机制, 拥有这一权限的用户
可以使用单一的ID和密码访问某个或多个系统从而避免使用不同的用户名或密码,或者通过某种配置无缝地登录每个系统,

它是目前比较流行的企业业务整合的解决方案之一,例如我们使用mis号登陆过公司的一个系统后,再登陆其他系统不用再次输入用户名和密码
这里写图片描述

单系统登录

单系统登录无需引入单点登录,登录后,登录状态保存在session中,并通过cookie给前端返回sessionId,前端后续的请求,浏览器会根据请求的域名在请求中加上相应的cookie,
服务端使用cookie中的sessionId,去session取出登录信息,判断登录状态和用户信息。
一个故事:学生时代去理发店理发,100块理9次,理发师给了我一个号码105,说你以后来报这个号码就可以了。每次我理完给他报105,他便拿出一个小本子,找到105,在上面画个杠,这是一个服务端保持用户状态的例子。
这里写图片描述

注意:

如果我们的系统很庞大,但是该系统并没有子系统,我们也不需要单点登录,我们需要的是搭建集群环境,多台主机负载均衡,并进行session共享就ok了
这里写图片描述

多系统单点登录

同域名不同站点

如果两个站点能够共享cookie,那么两个站点就能共享sessionId,也就意味着用户在站点A登录,站点B通过共享sessionId也能拿到session中的登录信息。

这将很容易实现同一个用户登录多个站点。

而HTTP协议天然支持同一个域名下的两个站点共享cookie,例如我们有两个站点:

www.sso.com/site1
www.sso.com/site2

如果用户登录了site1,浏览器将会保存一个cookie,对应的默认域名是www.sso.com,用户访问site2的时候,浏览器判断是同一个域名,将会在请求中加入cookie信息

这样的话,服务器端不需要修改

不同子域

两个站点的二级域名相同,但是三级域名不同,例如

d1.sso.comd2.sso.com

共享session

默认情况浏览器请求的时候,会根据域名发送该域名对应的cookie,也就是说,来自于d1.sso.com的cookie默认所属的域是.d1.sso.com,

请求d2.sso.com的时候不会发送d1的cookie,

这种情况下,我们可以设置两个域的cookie为同一个域,用户登录d1.sso.com后,服务端将cookie所属域名设置为.sso.com并返回,浏览器将会保存

.sso.com和cookie的对应关系,当用户访问d2.sso.com的时候,根据浏览器发送cookie规则,将会携带.sso.com对应的cookie,也就是d1.sso.com登录后产生的cookie。

服务端拿到cookie中的sessionId,到共享session中就能拿到用户的登录信息。
这里写图片描述

不同域

多个相关但彼此独立的系统,域名不同,登录其中的一个系统,访问其他系统就不需要再次登录,如

www.service1.com
www.service2.com

单点登录过程

在讲原理前先扯两个故事:原则:1.所有的游乐设施都有闸机2.每张票据属于一个系统。
故事一:小明同学今天来迪士尼(A.com)玩,来到门口闸机前发现没有票,这会他来到售票处,买了票,到闸机拿,刷票验证通过,进园。
故事二:有一天迪士尼(A.com)和欢乐谷(B.com)合作,规定只要买了任何一家乐园的门票就可以在规定的时间内逛两家乐园。可是问题来了,迪士尼的售票处只能卖迪士尼的门票,欢乐谷的售票处只能卖欢乐谷的门票,怎么设计才能解决这个,即Domain下的系统如何共享一份的验证信息?这时候我们有一种好的方案,即把售票处独立出来,成了新的公司(sso.com)。当小明到了迪士尼(A.com)后,发现没有票,去售票公司(SSO.com),售票公司给了小明一张票据,说你迪士尼指定的闸机那刷一下就可以了,小明来到闸机(callbackA)那刷一下(带着sso的票据去访问售票处的系统),sso的系统检测票据有效,给小明传回一张迪斯尼的门票,接下来小明拿着这张票可以访问任何项目了。这天下午小明又来了欢乐谷(B.com),到门口闸机处,发现没有门票,便带着sso的票据去售票公司,售票公司发现小明有票据,就让小明去欢乐谷指定的闸机刷一下,小明来到闸机(callbackB)那刷一下(带着sso的票据去访问售票处的系统),sso的系统检测票据有效,给小明传回一张欢乐谷(B.com)的门票,接下来小明拿着这张票可以访问任何项目了。

补充:1.其中故事一中迪士尼(A.com)和售票处(sso.A.com)属于一个域下面,所以售票处买的门票天然的可以访问任何A系统的应用。
2.只去售票公司两次(两次跳转sso页面),其他都是访问售票公司的系统服务。

这里写图片描述

  1. 用户未登录时访问系统A,系统A服务器检测到用户没登录(cookie中没有登录token),于是通知浏览器跳转到SSO服务站点,并在当前域名对应cookie中种上当前页面地址,以便登录后自动跳转回本页。

  2. sso服务站点检测到用户没有登录,于是显示登录界面。用户提交登录请求到服务端,服务端验证通过,创建和账号对应的用户登录凭据(token)。然后,服务端通知浏览器把该token放入sso服务站点对应的cookie中,并跳转回系统A在sso提前设置好的回调地址,跳回系统A的URL参数中会带上这个token。

  3. 浏览器在写sso服务站点cookie后,跳转回系统A。系统A服务端检测到浏览器请求的URL中带了单点登录的token,于是把这个token发到SSO服务站点验证。sso服务端站点验证通过后会返回系统A用户信息。系统A得到成功响应后,将token放入系统A域名对应的cookie中,从而完成在本站的登入以及会话保持。之后用户访问系统A时,都会带上这个cookie。

  4. 用户再访问系统B。系统B服务器检测到用户没登录,于是通知浏览器跳转到SSO服务站点。

  5. 浏览器访问SSO服务站点时会带上上述步骤2创建的sso域名对应的cookie(内有token)。sso服务站点根据该token能找到对应用户,于是通知浏览器跳转回系统B,并在跳转回去的URL参数中带上这个token。

  6. 系统B服务端检测到浏览器请求的URL中带上了单点登录的token,于是又会走上述对应步骤3,完成用户在本站的自动登录。

注意:

本方案设计有意思的点是,系统A和系统B重定向sso的时候,共享了sso域名对应的cookie(token),只要其中的一个系统登陆过,sso域名对应的

cookie中就存在token,另外的业务系统重定向sso的时候,sso可以从cookie中取出token,判断是不是可以自动登陆,可以自动登陆则重定向回业务系统,

否则显示登陆页面。

登录后请求过程

这里写图片描述

用户在某个系统登录后,后续的请求都会携带token,服务端获取token后会到sso进行校验,校验成功后会返回用户信息

服务端拿到用户信息后继续后面的操作

如果token失效,服务端将会清空cookie中的token然后进行单点登录的流程

退出登录

这里写图片描述

FAQ

  1. 商家修改密码需要下线么?

    根据业务需要,可以在sso中控制

  2. 能否实现让部分商家修改密码后不下线?

    可以,token生成不依赖用户密码,所以修改密码操作本身并不会使token失效

  3. 由于任何一个应用系统页面都要验证登录状态,sso服务负载会很高,如何解决?

    服务端可以对token=>userInfo做短时间的cache,比如10分钟,验证时先找cache中是否存在token,若存在直接返回userInfo,若不存在cache,验证登录成功同时写下cache

  4. token生成算法是否可以升级?

    在token中加入版本version字段

  5. token有期限,如何避免用户正浏览时掉线?

    token添加expiretime,决定token是否过期。当业务方访问的一个token的租约快要过期时,系统会自动给token续租。

    仅在token生成后,一个租约的时间内没有任何业务方访问时,该token才会失效,这样不会导致用户在使用中会突然掉线的情况。

对比

http协议是无状态协议。浏览器访问服务器时,要让服务器知道你是谁,只有两种方式:

方案一:把“你是谁”写入cookie,浏览器通过cookie保存用户信息相关凭据,随每次请求传递到服务端

方案二:在URL、表单数据中带上你的用户信息(也可能在HTTP头部)。这种方式依赖于从特定的网页入口进入,因为只有走特定的入口,才有机会拼装出相应的信息,提交到服务端。

大部分SSO需求都希望不依赖特定的网页入口(集成门户除外),所以后一种方式有局限性。适应性强的方式是第一种。

漫谈单点登录系统
单点登录sso:图示和讲解
SSO单点登录解决方案

原文地址:https://www.cnblogs.com/panpanwelcome/p/13609333.html