写点什么

单点登录实现思路和方案

  • 2023-05-05
    湖南
  • 本文字数:2608 字

    阅读完需:约 9 分钟

最近公司业务在拓展,如移动端需要使用公司的用户体系和公司内部的产品线需集成各应用子系统,考虑到身份验证、用户信息授权可扩展性、可复用性等问题,避免用户需要针对每个应用系统都进行独立的登录,我们研发团队对单点登录方案的讨论进入了议程。

什么是单点登录

单点登录(Single Sign-On, SSO)是一种身份验证机制,允许用户一次登录即可访问多个应用程序或系统,无需为每个应用程序或系统分别输入认证凭据,便可在其他所有系统中得到授权,无需再次登录。

单点登录解决什么问题

用户侧

  • 用户只需要一次身份验证即可访问多个应用程序或系统,从而简化了登录过程,提高了用户体验。

  • 减少了用户忘记密码或用户名的风险,因为只需要记住一个凭据。

  • 提升安全性,因为用户无需在每个应用程序或系统中输入密码,从而减少了密码泄露或人为错误的可能性。

公司侧

  • 减少了应用程序或系统中身份验证模块的开发和维护工作,因为这些模块可以集成到单个身份提供者中(如统一认证中心)。

  • 简化了用户管理和授权,使开发者可以使用单一的用户体系中心来管理和授权用户对多个应用程序或系统的访问。

  • 降低了开发成本和时间,因为开发者无需为每个应用程序或系统编写自己的身份验证逻辑,而是可以重用已有的用户体系。

单点登录的原理和实现方案

基本原理

  1. 用户登录:用户在任何一个应用程序或系统中进行身份验证,并提供他们的凭据。

  2. 认证系统验证:该凭据被发送到认证系统进行验证。如果凭据有效,则认证系统会为用户生成数字签名的令牌(如 token 或 ticket)。

  3. 令牌分发:认证系统将令牌返回给应用程序或子系统。

  4. 应用程序或系统授权:应用程序或系统使用令牌验证用户的身份,并授权其访问相应资源或服务。

  5. 跨域系统访问:用户可以通过同一令牌访问多个跨域应用程序或系统,而无需重复进行身份验证。

实现方案

单点登录的实现方案一般包含:Cookies、分布式 Session 方式、统一认证授权方式(JWT、OAuth2.0)等。目前解决跨域问题的比较常用的方案是分布式 Session 及统一认证授权方式。

Cookie 单点登录

基于 Cookie 的单点登录是最简单的单点登录实现方式,使用一个共享的 Cookie 作为用户身份验证凭据,并在多个应用程序或系统之间进行共享。当用户首次登录某个应用程序时,该应用程序会生成一个加密 Cookie,并将其发送到用户的浏览器中(后端接口返回响应头设置 cookie)。


随后,当用户尝试访问其他应用程序时,这些应用程序请求头会自动带上 cookie,后端使用其中的信息验证用户身份。这种方式虽然实现简单,但在 Android 和 iOS 应用程序中通常不直接使用 cookie 来处理数据(我猜测是因为不同的设备和操作系统可能对 cookie 的支持程度不同),因为 cookie 是一种在 web 浏览器中使用的机制,它的使用场景在浏览器端。同时它不支持跨域访问,如果需要在各应用网站共享 cookie,其对应的多个站点的顶级域名必须相同

分布式 Session 实现单点登录

其实这种方式的原理和 cookie 差不多,分布式 Session 实现单点登录原理是将用户认证信息保存于 Session 中,即以 Session 内存储的值为用户凭证,一般采用 Cache 中间件实现(如 Redis)。用户再次登录时,应用服务端获取分布式 Session 来校验用户信息。如图所示:

一般情况下都是基于 Redis 实现 Session 共享,将 Session 存储于 Redis 上,然后将整个系统的全局 Cookie Domain 设置于顶级域名(如 example.com)上,这样 SessionID 就能在各个子系统间共享。这种方式也有一个问题,共享 Session 无法处理跨顶级域名(如 example.cn、example.com、example.net 等)。

使用 JWT 实现单点登录

JWT (JSON Web Token)是一个开放标准,它是一个含签名并携带用户相关信息的加密串。使用 JWT 进行身份验证时,客户端将用户的登录信息发送给服务器,服务器通过验证后生成一个加密字符串,并将其返回给客户端。客户端在随后的请求头中携带该加密字符串,服务器接收到请求后解析加密字符串,验证其中的签名和有效期,然后根据携带的信息判断是否授权访问。


JWT(JSON Web Token)字符串主要包含以下三部分:

  1. Header(头部):由两部分组成,分别是令牌类型(通常为 JWT)和使用的加密算法(例如 HMAC SHA256 或 RSA)。

  2. Payload(载荷):也称为 Claims,包含了一些有关用户或实体的信息,例如身份验证状态、权限或其他元数据。Payload 可以包含多个声明(Claim),每个声明以键值对的形式出现,并且包含标准声明和自定义声明。标准声明包括 iss(令牌颁发者)、exp(令牌过期时间)、sub(令牌主题)等。

  3. Signature(签名):由 Header、Payload 和秘钥生成的签名,用于验证令牌是否合法和未被篡改。签名通常使用 Base64 编码后的 Header 和 Payload 和一个秘钥进行哈希运算生成。


其他网页应用结合 JWT 与分布式 session,实现多域多空间单点登录。通过 JWT 生成和校验令牌,将刷新令牌存储在 redis 中,网关统一校验令牌,校验通过后将用户信息设置在请求头中,应用在拦截器中获取到用户信息后即可验证通过。


不同域中的网站共用一套密钥并且实时同步用户信息,通过 JWT 生成和校验令牌,用户登录其中一个域后,前端获取 JWT 加密串并写入 Local Storage 中,当用户跳到到其他域的网站时前端传入该加密串,后端网关校验,由此实现免登录访问其他域资源,如下图所示:

使用 OAuth2.0 实现单点登录

OAuth 2.0 是一种认证授权机制,主要用来颁发令牌(ticket),OAuth 的核心就是向第三方应用颁发令牌,OAuth2.0 对应下图中的统一认证系统:

如图,通过统一认证授权方式实现单点登录,需要有一个统一的认证系统。用户第一次访问应用系统时,由于还未登录,被引导到认证系统中进行登录,认证系统接受用户名密码等安全信息,生成访问令牌(ticket)。用户通过 ticket 访问应用系统,应用系统接受到请求之后会访问认证系统检查 ticket 的合法性,如果检查通过,用户就可以在不用再次登录的情况下访问应用系统资源。


具体流程如下:

需要注意的是,为了实现这种方式的单点登录,所有涉及的子应用或系统都必须能够与认证中心进行集成,并使用相同的身份验证和授权协议(如 OAuth),如果想实现更安全的认证方式,可以使用多因素身份验证(密码、短信验证码等)。通过 OAuth2.0 认证实现单点登录,为开发人员提供了一个通用的身份验证框架,提高开发人员的效率,解决了跨顶级域名单点登录问题。

总结

实现单点登录的主流的技术方案很多,并不是说哪种方案最好,技术方案服务于业务,为业务赋能,我们需要针对具体应用场景来制定最优解决方案。


作者:上进是诗雯啊

链接:https://juejin.cn/post/7224017330723913783

来源:稀土掘金

用户头像

还未添加个人签名 2021-07-28 加入

公众号:该用户快成仙了

评论

发布
暂无评论
单点登录实现思路和方案_Java_做梦都在改BUG_InfoQ写作社区