你知道什么是单点登录SSO吗?来看看最详细的SSO讲解!

什么是单点登录(SSO)

单点登录的英文名叫做:Single Sign On (简称SSO),它是一种身份验证解决方案,可让用户通过一次性用户身份验证登录多个应用程序和网站 。想象一下你们公司有N多个业务系统,什么邮箱、CRM、报销、知识库等全都是你们公司的并且各个系统独立的,而你的工作需要每天都用上这些系统,所以你不得不挨个儿登录一个又一个系统,即便你把密码设置成一样的也还是很繁琐。那么你们公司就非常需要SSO了,他就是用来解决多个业务之间只需要登录一个既可,而无需重复登录。故名为:单点登录!

如何实现单点登录

单点登录的种类

单点登录根据域名不同分为同域SSO和不同域SSO,来看看区别:

同域名SSO

如果公司只有一个域名,通过二级域名区分不同的系统。比如公司有个域名 a.com同时有两个业务系统service1.a.com和service2.a.com。我们要做单点登录(SSO),需要一个登录系统 sso.a.com。用户只要在sso.a.com登录,那么service1.a.com和service2.a.com就也登录了。

用户在sso.a.com中登录之后,其实是在sso.a.com的服务端session中记录了登录状态,同时在浏览器端的sso.a.com下写入了Cookie。那么我们怎么才能让service1.a.com和service2.a.com登录呢?这里有两个问题:

  • Cookie跨域:Cookie是不能跨域的,Cookie的domain属性是sso.a.com,在给service1.a.com和service2.a.com发送请求是带不上的。
  • Session不共享:sso、service1和service2是不同的应用,它们的session存在自己的应用内,是不共享的。 针对第一个问题,sso登录以后,可以将Cookie的域设置为顶域,即.a.com,这样所有子域的系统都可以访问到顶域的Cookie。也就是.a.com这个域名下。

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

同域下的单点登录是巧用了Cookie顶域的特性。实现起来很简单,但是很多时候域名是不一样的...

不同域名SSO

对于不同的域名,我们就使用不了顶层域cookie的手段了。

单点登录的魔力在于它巧妙地分离了 "认证 (Authentication) " 和 "授权访问应用 (Access to Application) " 这两个动作,并通过可信的第三方(身份提供者 - Identity Provider, IdP)用户(User)、应用(Service Provider, SP)IdP 之间建立信任链。其核心思想是:

  • 认证中心化: 用户只在一个地方(IdP) 登录一次,证明自己的身份。
  • 信任传递: IdP 向用户访问的各个应用(SP) 安全地传递一个证明(Assertion/Token),证明"这个用户已经在我这里登录过了,他是谁(身份标识)"。
  • 应用信任 IdP: 应用(SP)信任 IdP 发出的证明(通过加密签名、密钥验证等方式确保证明真实且未被篡改)。
  • 建立本地会话: 应用(SP)验证证明有效后,为用户在其自身系统内创建一个登录会话(Session),允许用户访问。用户无需再向该应用提供用户名密码。

关键在于:应用(SP)自己不再执行主要的用户名密码认证过程,而是委托并信任 IdP 的认证结果。

有点拖沓了,直接上图:

service2访问:

我在用口水话讲一下逻辑。假设现在有三个域名的系统:

service1对应上图应用(service provider),认证中心就是(身份提供者)。

  1. 假设用户第一次登录service1,此时service1发现用户并没有登录。随即重定向到SSO,并附带自己的地址参数。如:www.sso.com?service=www.service1.com
  2. 到了SSO后,认证中心发现用户没有登录,跳转登录。用户登录完成后,SSO根据用户信息生成session存到服务器端并生成token返回给浏览器存在SSO的域名下,也就是sso.com 。同时SSO还会生成一个来令牌(后面解释 )。然后根据service1的重定向地址跳转到service1,同时在连接上带上这个令牌,如:www.service1.com?token=xxxxxxx
  3. 回到service1后,service1拿到令牌去调用SSO的服务端接口验证令牌是否合法。SSO拿到令牌后,与服务端session比对,合法后返回token给service1.service1拿到token存在本域名下。即:service1.com。到此service1的登录完成了。
  4. 很好,那如果此时用户访问service2呢,service2肯定没有登录,此时,service2也带上自己的地址参数去访问SSO。此时的SSO已经通过service1登录过了,SSO会先请求验证是否有登录以及登录是否有效。发现已经登录成功了,随即跳过登录认证步骤,直接返回令牌给service2,service拿到后就和service1一样的操作了。注意:验证是否登录的操作是在SSO里面完成的,所以SSO能拿到在sso.com域名下的Cookie

到此,SSO的授权多系统登录就完成了。

拓展疑问

  1. 在第一个案例中使用顶层域名来存贮和自动携带cookie的方式里面,能不能存多个域名来实现SSO?就不用第二种方式那么麻烦了。

在设置 Cookie 的 Domain 属性时,不允许指定多个域名。这是由 HTTP Cookie 标准(RFC 6265)明确规定的行为。

  1. 在第二个方案中,是否有可以让SSO直接返回各个service系统可以直接使用的token,而不是令牌,因为拿到令牌后还要去验证一次,登录链条过长且用户可能感知到很慢。

这个问题的话,需要根据自身业务情况去取舍,如果想要快速一些,可以在SSO返回的token里面进行一些加密处理。service拿到后再去解析出来,这样可以节省一个请求,确实会快一些。

but,缺点就是,再返回的过程中被拦截了,用户信息容易暴露,有安全隐患。因为通常我们令牌有效期非常短,可能就只有几秒钟。安全性更高

感谢阅读,如果对你有帮助,请多多点个关注,感谢支持

相关推荐
涡能增压发动积21 小时前
同样的代码循环 10次正常 循环 100次就抛异常?自定义 Comparator 的 bug 让我丢尽颜面
后端
Wenweno0o21 小时前
0基础Go语言Eino框架智能体实战-chatModel
开发语言·后端·golang
于慨21 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
石小石Orz21 小时前
油猴脚本实现生产环境加载本地qiankun子应用
前端·架构
swg32132121 小时前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
从前慢丶21 小时前
前端交互规范(Web 端)
前端
tyung21 小时前
一个 main.go 搞定协作白板:你画一笔,全世界都看见
后端·go
gelald21 小时前
SpringBoot - 自动配置原理
java·spring boot·后端
CHU72903521 小时前
便捷约玩,沉浸推理:线上剧本杀APP功能版块设计详解
前端·小程序
GISer_Jing21 小时前
Page-agent MCP结构
前端·人工智能