关于sso的认识

sso:single sign on (单点登录)

解释就是说:在多个应用系统中,只要等登录一次,就可以访问其他的受信任的应用系统。

普通的登录认证机制:
在我们用浏览器访问一个应用时,填写登录名和密码,完成登录的验证。这个时候我们这个登录的用户的session中的标记登陆状态就会变为yes(已登录),同时在浏览器中将这个用户的信息写入到cookie中,这个cookie是这个用户的唯一标识。
下次我们再访问这个应用的时候,就会在请求中带上这个cookie,服务端会根据这个cookie找到对应的session,通过session来判断这个用户是否登录。如果不做特殊配置,这个Cookie的名字叫做jsessionid,值在服务端(server)是唯一的。

同父域登录


比如有两个应用系统app1.a.com,和app2.a.com,还有一个sso.a.com登录系统。
我们只要在sso.a.com登录,app1.a.com和app2.a.com就也登录了。通过上面的登陆认证机制,我们可以知道,在sso.a.com中登录了,其实是在sso.a.com的服务端的session中记录了登录状态,同时在浏览器端(Browser)的sso.a.com下写入了Cookie。那么我们怎么才能让app1.a.com和app2.a.com登录呢?这里有两个问题:

1.Cookie是不能跨域的,我们Cookie的domain属性是sso.a.com,在给app1.a.com和app2.a.com发送请求是带不上的

2 sso、app1和app2是不同的应用,它们的session存在自己的应用内,是不共享的

那么我们如何解决这两个问题呢?针对第一个问题,sso登录以后,可以将Cookie的域设置为顶域,即.a.com,这样所有子域的系统都可以访问到顶域的Cookie。我们在设置Cookie时,只能设置顶域和自己的域,不能设置其他的域。比如:我们不能在自己的系统中给baidu.com的域设置Cookie。

Cookie的问题解决了,我们再来看看session的问题。我们在sso系统登录了,这时再访问app1,Cookie也带到了app1的服务端(Server),app1的服务端怎么找到这个Cookie对应的Session呢?这里就要把3个系统的Session共享,。共享Session的解决方案有很多,例如:Spring-Session。这样第2个问题也解决了。

同域下的单点登录就实现了,但这还不是真正的单点登录

跨域

同域下的单点登录是巧用了Cookie顶域的特性。如果是不同域呢?不同域之间Cookie是不共享的,怎么办?

这里我们就要说一说CAS呢。

CAS(*认证服务器)
AS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。图1 是 CAS 最基本的协议过程:
cas 协议图
关于sso的认识
cas 协议图
CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 Service Ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 CAS Server 登录地址,并传递 Service (也就是要访问的目的资源地址),以便登录成功过后转回该地址。用户在第 3 步中输入认证信息,如果登录成功,CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket,并缓存以待将来验证,之后系统自动重定向到 Service 所在地址,并为客户端浏览器设置一个 Ticket Granted Cookie(TGC),CAS Client 在拿到 Service 和新产生的 Ticket 过后,在第 5,6 步中与 CAS Server 进行身份核实,以确保 Service Ticket 的合法性。(摘自百度百科)

具体流程是:

用户要去访问app1.a.com,没有登陆,所以要先去登陆,
跳转到cas.server,就是sso.a.com,用户输入登录信息,登陆成功,

TGT:Ticket Grangting Ticket
TGT 是 CAS 为用户签发的登录票据,拥有了 TGT,用户就可以证明自己在 CAS 成功登录过。TGT 封装了 Cookie 值以及此 Cookie 值对应的用户信息。当 HTTP 请求到来时,CAS 以此 Cookie 值(TGC)为 key 查询缓存中有无 TGT ,如果有的话,则相信用户已登录过。

TGC:Ticket Granting Cookie
CAS Server 生成TGT放入自己的 Session 中,而 TGC 就是这个 Session 的唯一标识(SessionId),以 Cookie 形式放到浏览器端,是 CAS Server 用来明确用户身份的凭证。

ST:Service Ticket
ST 是 CAS 为用户签发的访问某一 service 的票据。用户访问 service 时,service 发现用户没有 ST,则要求用户去 CAS 获取 ST。用户向 CAS 发出获取 ST 的请求,CAS 发现用户有 TGT,则签发一个 ST,返回给用户。用户拿着 ST 去访问 service,service 拿 ST 去 CAS 验证,验证通过后,app系统将登录状态写入session并设置app域下的Cookie,允许用户访问资源。

然后用户想去访问app2.a.com,先跳转到sso.a.com登陆,sso已经登陆过了,所以sso生成ST,浏览器跳转到app2.a.com中,并且将ST作为参数传递给app2.a.com,app2拿到ST后,后台访问sso,验证ST是否有效,验证成功后,app2将登录状态写入session,并在app2域下写入Cookie。

用户在成功访问app1.a.com后,再访问app2.a.com的时候需要再次验证传递过来的ST是否有效,是防止用户信息是伪造的,如果我在SSO没有登录,而是直接在浏览器中敲入回调的地址,并带上伪造的用户信息,是不是业务系统也认为登录了呢?这是很可怕的。

以上很多内容是参照https://www.jianshu.com/p/75edcc05acfd的内容!!!