单点登录(Single Sign On,SSO)是一种身份验证解决方案,作用是在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统
在说单点登录(SSO)的技术实现之前,先说一说普通的登录认证机制。
![[Pasted image 20240404102812.png]]
在浏览器(Browser)中访问一个应用,这个应用需要登录,用户填写完用户名和密码后,完成登录认证。这时,服务器(Server)在这个用户的 session 中标记登录状态为 true(已登录),同时在浏览器中写入 Cookie,这个 Cookie 是这个用户的唯一标识。用户下次再访问这个应用的时候,请求中会带上这个 Cookie,服务端会根据这个 Cookie 找到对应的 session,通过 session 来判断这个用户是否登录。
一个企业一般情况下只有一个域名,通过二级域名区分不同的系统。比如有个域名叫做:a.com,同时有两个业务系统分别为:app1.a.com 和 app2.a.com。要做单点登录(SSO),需要一个登录系统,叫做:sso.a.com。
只要在 sso.a.com 登录,app1.a.com 和 app2.a.com 就也登录了。通过上面的登陆认证机制可以知道,在 sso.a.com 中登录了,其实是在 sso.a.com 的服务端的 session 中记录了登录状态,同时在浏览器端的 sso.a.com 下写入了 Cookie。那么怎么才能让 app1.a.com 和 app2.a.com 登录呢?这里有两个问题:
sso.a.com,在给 app1.a.com 和 app2.a.com 发送请求是带不上的。sso、app1 和 app2 是不同的应用,它们的 session 存在自己的应用内,是不共享的。如何解决这两个问题呢?
sso 登录以后,可以将 Cookie 的域设置为顶域,即 .a.com,这样所有子域的系统都可以访问到顶域的 Cookie。注意:在设置 Cookie 时,只能设置顶域和自己的域,不能设置其他的域。比如不能在自己的系统中给 baidu.com 的域设置 Cookie。![[Pasted image 20240404103406.png]]
同域下的单点登录是巧用了 Cookie 顶域的特性,但这还不是真正的单点登录。
CAS 流程是单点登录的标准流程:
![[CAS.png]]
至此,跨域单点登录就完成了。以后再访问 app 系统时,app 就是登录的。接下来,再看看访问 app2 系统时的流程:
这样,app2 系统不需要走登录流程,就已经是登录了。SSO、app 和 app2 在不同的域,它们之间的 session 不共享也是没问题的。
SSO 系统登录后,跳回原业务系统时,带了个参数 ST,业务系统还要拿 ST 再次访问 SSO 进行验证,这个步骤是不是有点多余?
答:这个步骤是必不可少的!如果在 SSO 没有登录,而是直接在浏览器中敲入回调的地址,并带上伪造的用户信息,就可以绕过登录认证了,这是很可怕的。
上面只是以 session 为例,使用其他登录认证方式(如:[[005.JWT|Token]])也是可以的
SSO 解决方案使用不同的标准和协议来对用户凭证进行验证和身份验证。
SAML(安全断言标记语言)是应用程序用来与 SSO 服务交换身份验证信息的协议或规则集。SAML 使用 XML(一种浏览器友好的标记语言)来交换用户标识数据。基于 SAML 的 SSO 服务提供更好的安全性和灵活性,因为应用程序不需要在其系统上存储用户凭证。
[[006.OAuth2|OAuth]](开放授权)是一种开放标准,它允许应用程序安全地从其他网站获取用户信息,而无需提供密码。应用程序不是请求用户密码,而是使用 OAuth 来获得用户访问受密码保护的数据的权限。OAuth 通过 API 建立应用程序之间的信任,允许应用程序在已建立的框架中发送和响应身份验证请求。
OpenID 是使用一组用户凭证访问多个站点的方法。它允许服务提供商承担验证用户凭证的角色。Web 应用程序不是将身份验证令牌传递给第三方身份提供商,而是使用 OIDC 来请求附加信息并验证用户的真实性。
Kerberos 是一种基于票证的身份验证系统,可让两方或多方在网络上相互验证其身份。它使用安全密码学来防止未经授权访问在服务器、客户端和密钥分发中心之间传输的标识信息。