浅谈【单点登录】

2,001 阅读12分钟

前言

在数字化时代,用户访问多个应用程序和服务已成为常态。无论是企业内部的办公系统,还是面向公众的在线服务,用户往往需要在不同的平台上进行身份验证。然而,频繁的登录操作不仅繁琐,还可能降低用户体验,甚至成为安全漏洞的温床。为了解决这一问题,单点登录(Single Sign-On,简称SSO)应运而生。

什么是单点登录?

单点登录(Single Sign-On,简称SSO)是一种身份验证机制,允许用户使用一组凭据(通常是用户名和密码)登录到一个系统后,无需再次输入凭据即可访问其他相关系统。SSO的主要目的是简化用户的登录过程,提高用户体验,并减少用户在多个系统中管理多个账户的负担。

单点登录的工作原理

  1. 身份验证中心(Identity Provider, IdP) :SSO系统通常有一个中央身份验证中心,用户在这个中心进行一次登录。
  2. 服务提供者(Service Provider, SP) :用户需要访问的其他系统(子系统)被称为服务提供者。这些系统信任身份验证中心,并允许用户在通过身份验证后访问它们。
  3. 令牌(Token) :用户在身份验证中心登录后,会获得一个令牌(通常是一个加密的会话标识符)。这个令牌会被传递给服务提供者,服务提供者通过验证这个令牌来确认用户的身份。

单点登录的优点

  1. 简化用户登录过程:用户只需登录一次,即可访问多个相关的子系统,无需重复输入凭据。
  2. 提高用户体验:减少用户在多个系统中管理多个账户的负担。
  3. 增强安全性:通过集中管理用户身份和权限,减少安全漏洞。
  4. 降低管理成本:集中管理用户身份和权限,减少重复工作。

单点登录的缺点

  1. 实现复杂:不同的SSO实现方式有不同的复杂性,需要根据具体需求选择合适的方式。
  2. 安全性依赖:SSO系统的安全性依赖于身份验证中心的安全性,一旦身份验证中心被攻破,所有信任该中心的系统都可能受到影响。
  3. 跨域问题:跨域的SSO实现需要特殊处理,增加了实现的复杂性。

单点登录的实现方式


实现方式适用场景实现步骤优点缺点
基于Cookie的SSO适用于Web应用,尤其是同域或跨域的子系统。1. 创建一个中央身份验证中心(IdP),用户在这里进行登录。
2. IdP登录成功后,设置一个包含用户身份信息的Cookie。
3. 子系统信任IdP设置的Cookie,并使用它来验证用户身份。
1. 实现简单,适用于同域或跨域的Web应用。
2. 用户登录后,无需再次输入凭据。
1. 跨域问题需要特殊处理(如使用CORS或服务器端代理)。
2. 安全性依赖于Cookie的安全性。
基于OAuth 2.0/OpenID Connect的SSO适用于Web应用、移动应用和API服务。1. 使用OAuth 2.0或OpenID Connect协议作为身份验证中心(IdP)。
2. 用户在IdP登录后,IdP会颁发一个访问令牌(AccessToken)和一个身份令牌(ID Token)。
3. 子系统使用这些令牌来验证用户身份。
1. 支持多种客户端类型(Web、移动、API)。
2. 安全性高,令牌可以加密和签名。
1. 实现相对复杂,需要理解OAuth 2.0/OpenID Connect协议。
2. 需要处理令牌的颁发、验证和刷新。
基于SAML的SSO适用于企业内部应用和B2B场景。1. 使用SAML协议作为身份验证中心(IdP)。
2. 用户在IdP登录后,IdP会生成一个SAML断言(Assertion),包含用户身份信息。
3. 子系统使用SAML断言来验证用户身份。
1. 广泛应用于企业内部和B2B场景。
2. 支持多种身份验证方式(如LDAP、AD)。
1. 实现复杂,需要理解SAML协议。
2. 配置和调试相对困难。
基于JWT(JSON Web Token)的SSO适用于Web应用、移动应用和API服务。1. 用户在身份验证中心(IdP)登录后,IdP会生成一个JWT。
2. JWT包含用户身份信息,并使用密钥签名。
3. 子系统使用相同的密钥验证JWT的签名,并提取用户身份信息。
1. 轻量级,易于实现和使用。
2. 支持跨域和跨平台。
1. 安全性依赖于密钥的管理。
2. 令牌一旦颁发,无法撤销(除非设置过期时间)。
基于CAS(Central Authentication Service)的SSO适用于企业内部应用和教育机构。1. 部署一个CAS服务器作为身份验证中心。
2. 子系统集成CAS客户端,信任CAS服务器的身份验证结果。
3. 用户在CAS服务器登录后,CAS服务器会生成一个票据(Ticket),子系统使用这个票据来验证用户身份。
1. 开源,社区支持广泛。
2. 支持多种身份验证方式(如LDAP、AD)。
1. 配置和部署相对复杂。
2. 需要维护CAS服务器。

以上就是小编在网上搜集资料后总结出来的几种实现方案,不过小编在企业中听的比较多的是如下三种方式,或许是表达的术语有所差异,以下三种实现方式可能实现原理就是上述的某一种,不过小编没有搜寻到足够的资料证明,有待商榷,有明白的大佬还请在评论区指正,小编将不胜感激,也防止我的文章对读者产生误导性...

Session+Cookie、Token和双Token方式实现单点登录

实现方式Session+CookieToken双Token
原理1. 用户登录后,服务器生成一个Session ID。
2. Session ID存储在服务器端,用户信息存储在Session中。
3. Session ID通过Cookie传递给客户端。
4. 客户端每次请求时,携带Cookie中的Session ID。
5. 服务器根据Session ID查找对应的Session,验证用户身份。
1. 用户登录后,服务器生成一个Token(通常是JWT)。
2. Token包含用户信息,并使用密钥签名。
3. Token通过响应返回给客户端。
4. 客户端每次请求时,携带Token。
5. 服务器验证Token的签名,提取用户信息。
1. 用户登录后,服务器生成两个Token:访问令牌(Access Token)和刷新令牌(Refresh Token)。
2. Access Token用于短期访问,Refresh Token用于获取新的Access Token。
3. Access Token通过响应返回给客户端,Refresh Token通常存储在安全的地方(如HttpOnly Cookie)。
4. 客户端每次请求时,携带Access Token。
5. 服务器验证Access Token,如果过期,客户端使用Refresh Token获取新的Access Token。
优点1. 实现简单,适用于同域应用。
2. 服务器端存储用户信息,安全性较高。
3. 支持会话管理,可以随时撤销会话。
1. 无状态,服务器无需存储用户信息,扩展性好。
2. 支持跨域和跨平台。
3. 轻量级,易于实现和使用。
1. 安全性高,Refresh Token存储在安全的地方,不易被窃取。
2. 支持Token刷新,减少用户频繁登录。
3. 适用于需要长期会话的场景。
缺点1. 服务器需要存储Session,扩展性差。
2. 跨域问题需要特殊处理。
3. 安全性依赖于Cookie的安全性。
1. Token一旦颁发,无法撤销(除非设置过期时间)。
2. 安全性依赖于密钥的管理。
3. Token可能较大,影响性能。
1. 实现相对复杂,需要处理Token的颁发、验证和刷新。
2. 需要额外的存储和处理Refresh Token。
适用场景1. 同域Web应用。
2. 需要会话管理的场景。
3. 安全性要求较高的场景。
1. 跨域和跨平台应用。
2. 无状态应用。
3. 轻量级应用。
1. 需要长期会话的场景。
2. 安全性要求高的场景。
3. 需要Token刷新的场景。
安全性1. 安全性较高,服务器端存储用户信息。
2. 支持会话管理,可以随时撤销会话。
1. 安全性依赖于密钥的管理。
2. Token一旦颁发,无法撤销(除非设置过期时间)。
1. 安全性高,Refresh Token存储在安全的地方,不易被窃取。
2. 支持Token刷新,减少用户频繁登录。
扩展性1. 扩展性差,服务器需要存储Session。
2. 适用于同域应用。
1. 无状态,扩展性好。
2. 支持跨域和跨平台。
1. 扩展性较好,但需要处理Token的颁发、验证和刷新。
2. 适用于需要长期会话的场景。

总结:

  • Session+Cookie:适用于同域Web应用,安全性较高,但扩展性差。服务器压力也比较大,因为服务器需要存储Session
  • Token:适用于跨域和跨平台应用,无状态,扩展性好,但安全性依赖于密钥管理
  • 双Token:适用于需要长期会话和安全性要求高的场景,支持Token刷新,但实现相对复杂。

选择哪种方式实现单点登录取决于具体需求和技术栈。每种方式都有其优缺点,需要根据实际情况进行选择和配置。

实现过程

单点登录(Single Sign-On, SSO)的实现过程通常涉及一个中央认证中心(Identity Provider, IdP)和多个子系统(Service Provider, SP)。以下是单点登录的实现过程描述:

1. 用户在子系统A登录

  1. 用户访问子系统A:用户尝试访问子系统A,但尚未登录。
  2. 重定向到认证中心:子系统A检测到用户未登录,将用户重定向到中央认证中心(IdP)进行身份验证。
  3. 用户登录:用户在认证中心输入用户名和密码进行登录。
  4. 颁发令牌:认证中心验证用户身份后,颁发一个令牌(如JWT),并将用户重定向回子系统A。
  5. 存储令牌:子系统A接收到令牌后,通常将其存储在客户端(如Cookie、localStorage或者 sessionStorage)中。

2. 用户访问子系统B

  1. 用户访问子系统B:用户尝试访问子系统B,但尚未登录。
  2. 重定向到认证中心:子系统B检测到用户未登录,将用户重定向到中央认证中心(IdP)进行身份验证。
  3. 认证中心验证令牌:认证中心检查用户是否已经登录(通过检查存储在Cookie、localStorage或者 sessionStorage中的令牌)。
  4. 重定向回子系统B:如果用户已经登录,认证中心将用户重定向回子系统B,并附带令牌。
  5. 存储令牌:子系统B接收到令牌后,通常将其存储在客户端(如Cookie、localStorage或者 sessionStorage)中。

3. 中间跳转页面

在单点登录过程中,通常会有一个中间跳转页面(也称为“跳板页面”或“中间件页面”),用于处理重定向和令牌传递。这个页面通常由认证中心提供,用于确保用户在不同子系统之间的无缝切换。

4. 子系统B如何知道用户已登录

  1. 令牌验证:子系统B接收到令牌后,会验证令牌的有效性(如签名、过期时间等)。
  2. 用户信息提取:如果令牌有效,子系统B会从令牌中提取用户信息,并允许用户访问受保护的资源。
  3. 无需再次登录:由于用户已经在认证中心登录并获得了有效的令牌,子系统B不会跳转到登录页面,而是直接允许用户访问。

5. 中间跳转页面的作用

  1. 重定向:中间跳转页面负责将用户从子系统A重定向到认证中心,并在用户登录后将用户重定向回子系统A。
  2. 令牌传递:中间跳转页面负责在用户登录后将令牌传递给子系统A,并在用户访问子系统B时将令牌传递给子系统B。
  3. 无缝切换:中间跳转页面确保用户在不同子系统之间的切换是无缝的,用户无需再次输入凭据。

示例代码

以下是一个简单的中间跳转页面的示例代码,展示如何将令牌存储在 sessionStorage 中:

<!-- sso-redirect.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SSO Redirect</title>
</head>
<body>
  <script>
    // 获取URL参数
    function getUrlParam(name) {
      const urlParams = new URLSearchParams(window.location.search);
      return urlParams.get(name);
    }

    // 获取令牌
    const token = getUrlParam('token');
    const targetUrl = getUrlParam('target');

    if (token && targetUrl) {
      // 将令牌存储在sessionStorage中
      sessionStorage.setItem('access_token', token);
      // 重定向到目标URL
      window.location.href = targetUrl;
    } else {
      // 如果没有令牌或目标URL,重定向到登录页面
      window.location.href = '/login';
    }
  </script>
</body>
</html>

总结

单点登录的实现过程涉及以下关键步骤:

  1. 用户在子系统A登录:用户在认证中心登录,并获得令牌。
  2. 用户访问子系统B:子系统B通过认证中心验证令牌,并允许用户访问。
  3. 中间跳转页面:负责处理重定向和令牌传递,确保用户在不同子系统之间的无缝切换。

通过这种方式,用户在子系统A登录后,访问子系统B时无需再次登录,认证中心负责验证用户身份并颁发令牌,不同的子系统信任认证中心颁发的令牌,从而实现单点登录。

希望本文能够帮助您更好地理解单点登录的实现过程、优缺点和适用场景,为您在实际项目中的应用提供有价值的参考。感谢阅读!!!

参考: