单点登录(Single Sign On,SSO)是一种身份验证解决方案,作用是在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统

技术实现

在说单点登录(SSO)的技术实现之前,先说一说普通的登录认证机制。

普通的登录认证机制

![[Pasted image 20240404102812.png]]

在浏览器(Browser)中访问一个应用,这个应用需要登录,用户填写完用户名和密码后,完成登录认证。这时,服务器(Server)在这个用户的 session 中标记登录状态为 true(已登录),同时在浏览器中写入 Cookie,这个 Cookie 是这个用户的唯一标识。用户下次再访问这个应用的时候,请求中会带上这个 Cookie,服务端会根据这个 Cookie 找到对应的 session,通过 session 来判断这个用户是否登录。

同域下的单点登录

一个企业一般情况下只有一个域名,通过二级域名区分不同的系统。比如有个域名叫做:a.com,同时有两个业务系统分别为:app1.a.comapp2.a.com。要做单点登录(SSO),需要一个登录系统,叫做:sso.a.com

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

如何解决这两个问题呢?

![[Pasted image 20240404103406.png]]

同域下的单点登录是巧用了 Cookie 顶域的特性,但这还不是真正的单点登录。

不同域下的单点登录

CAS 流程是单点登录的标准流程:

![[CAS.png]]

  1. 用户访问 app 系统,app 系统是需要登录的,但用户现在没有登录。
  2. 跳转到 CAS server,即 SSO 登录系统,SSO 系统也没有登录,弹出用户登录页。
  3. 用户填写用户名、密码,SSO 系统进行认证后,将登录状态写入 SSO 的 session,浏览器中写入 SSO 域下的 Cookie。
  4. SSO 系统登录完成后会生成一个 ST(Service Ticket),然后跳转到 app 系统,同时将 ST 作为参数传递给 app 系统。
  5. app 系统拿到 ST 后,从后台向 SSO 发送请求,验证 ST 是否有效。
  6. 验证通过后,app 系统将登录状态写入 session 并设置 app 域下的 Cookie。

至此,跨域单点登录就完成了。以后再访问 app 系统时,app 就是登录的。接下来,再看看访问 app2 系统时的流程:

  1. 用户访问 app2 系统,app2 系统没有登录,跳转到 SSO。
  2. 由于 SSO 已经登录了,不需要重新登录认证。
  3. SSO 生成 ST,浏览器跳转到 app2 系统,并将 ST 作为参数传递给 app2。
  4. app2 拿到 ST,后台访问 SSO,验证 ST 是否有效。
  5. 验证成功后,app2 将登录状态写入 session,并在 app2 域下写入 Cookie。

这样,app2 系统不需要走登录流程,就已经是登录了。SSO、app 和 app2 在不同的域,它们之间的 session 不共享也是没问题的。

注意

SSO 系统登录后,跳回原业务系统时,带了个参数 ST,业务系统还要拿 ST 再次访问 SSO 进行验证,这个步骤是不是有点多余?

答:这个步骤是必不可少的!如果在 SSO 没有登录,而是直接在浏览器中敲入回调的地址,并带上伪造的用户信息,就可以绕过登录认证了,这是很可怕的。

上面只是以 session 为例,使用其他登录认证方式(如:[[005.JWT|Token]])也是可以的

SSO 有哪些类型?

SSO 解决方案使用不同的标准和协议来对用户凭证进行验证和身份验证。

SAML

SAML(安全断言标记语言)是应用程序用来与 SSO 服务交换身份验证信息的协议或规则集。SAML 使用 XML(一种浏览器友好的标记语言)来交换用户标识数据。基于 SAML 的 SSO 服务提供更好的安全性和灵活性,因为应用程序不需要在其系统上存储用户凭证。

OAuth

[[006.OAuth2|OAuth]](开放授权)是一种开放标准,它允许应用程序安全地从其他网站获取用户信息,而无需提供密码。应用程序不是请求用户密码,而是使用 OAuth 来获得用户访问受密码保护的数据的权限。OAuth 通过 API 建立应用程序之间的信任,允许应用程序在已建立的框架中发送和响应身份验证请求。

OIDC

OpenID 是使用一组用户凭证访问多个站点的方法。它允许服务提供商承担验证用户凭证的角色。Web 应用程序不是将身份验证令牌传递给第三方身份提供商,而是使用 OIDC 来请求附加信息并验证用户的真实性。

Kerberos

Kerberos 是一种基于票证的身份验证系统,可让两方或多方在网络上相互验证其身份。它使用安全密码学来防止未经授权访问在服务器、客户端和密钥分发中心之间传输的标识信息。