你知道什么是单点登录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,缺点就是,再返回的过程中被拦截了,用户信息容易暴露,有安全隐患。因为通常我们令牌有效期非常短,可能就只有几秒钟。安全性更高

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

相关推荐
-凌凌漆-3 小时前
【npm】npm的-D选项介绍
前端·npm·node.js
鹿心肺语3 小时前
前端HTML转PDF的两种主流方案深度解析
前端·javascript
程序员良许3 小时前
三极管推挽输出电路分析
后端·嵌入式
Java水解3 小时前
【JAVA 进阶】Spring AOP核心原理:JDK与CGLib动态代理实战解析
后端·spring
Java水解3 小时前
Spring Boot 4 升级指南:告别RestTemplate,拥抱现代HTTP客户端
spring boot·后端
宫水三叶的刷题日记3 小时前
工商银行今年的年终奖。。
后端
大黄评测4 小时前
双库协同,各取所长:.NET Core 中 PostgreSQL 与 SQLite 的优雅融合实战
后端
海石4 小时前
去到比北方更北的地方—2025年终总结
前端·ai编程·年终总结
Java编程爱好者4 小时前
Java 后端定时任务怎么选:@Scheduled、Quartz 还是 XXL-Job?
后端
Java编程爱好者4 小时前
线程池用完不Shutdown,CPU和内存都快哭了
后端