单点登录的设计与实现思路

发布时间 2023-09-24 22:43:13作者: 那么远这么近

1.定义

单点登录 (Single sign-on ,缩写为 SSO),一种对于许多相互关连,但是又是各自独立的软件系统,提供“存取控制” 的属性。 当拥有这项属性时,当用户“登录”时,就可以获取所有系统的存取权限,不用对每个单一系统都逐一登录。

2.概述

随着业务的发展,产品的功能越来越多,越来越重,这时候就需要将各业务模块拆分成一个独立的应用,每个应用再专注的发展自己的业务特点。然而这些应用又彼此互联,它们共用一套用户基础数据,这个基础数据就是公司的用户数据中心。例如,淘宝首页嵌套有“天猫”、“飞猪”、“聚划算”等,一旦登录了淘宝帐号,便可直接以登录状态跳转到各个链接的应用中。

单点登录就是这种彼此互联又相互独立的软件登录场景中的一种“设计思想”,用来实现“一次登录,处处使用”。注意,单点登录只是一种思想,而不是一种技术,实现它的最常用技术是OAuth,接下来会讲到这个技术。

3.基本原理

参与角色

浏览器端:Cookie中存放应用1、应用2、认证中心的sessionid,后续同域名的请求header头中自动携带该cookie

应用1:对应公司内的某个应用,在其数据库中会维护一份有关于该应用的的用户信息,有自己的登录服务1、应用服务1

应用2:对应公司内的某个应用,在其数据库中会维护一份有关于该应用的的用户信息,有自己的登录服务2、应用服务2

认证中心:有个用户数据中台,放在公司官网中注册的用户信息(用户名、密码)

前提条件

在公司官网中(数据保存到认证中心)验证通过的用户名密码必须能在公司各应用(数据保存到各应用数据库)登录服务中验证通过

 

  •  第一步,新打开一个浏览器,在浏览器页签中打开资源1的URL,由于此时是第一次请求,当前域名cookie中无session信息,资源1的后端服务鉴权中心发现没有登录信息(一般在资源服务器之前有网关层,网关层中做鉴权认证,通常使用cookie中的sessionId去分布式缓存中换取用户信息),就直接302重定向到登录服务。
  • 第二步,用户输入登录信息,请求到应用1的登录服务1,登录服务1去认证中心验证用户名密码,验证通过后,将获取到的token返回给登录服务1。登录服务1和认证中心都会在自己的分布式缓存中维护登录状态和用户信息(用户信息是一个键值对,键会在浏览器端的cookie中保存一份,值是序列化的用户信息),同时会向前端Cookie中设置两个sessionid,一个是应用1的sessionid1(cookie的作用域是应用1的域名),一个是认证中心的sessionid-auth(cookie的作用域是认证中心的域名)。
  • 第四步,浏览器端判断登录成功后,header头cookie中自动携带应用1的sessionid信息,重定向访问资源1,后端根据sessionid1从分布式缓存中获取到用户信息,当登录状态设置到当前请求上下文中。业务数据处理完成后返回给浏览器端。
  • 第五步,浏览器继续请求下一个应用1的资源数据,header头cookie中依然自动携带应用1的sessionid信息,后端根据sessionid1从分布式缓存中获取到用户信息,当登录状态设置到当前请求上下文中。业务数据处理完成后返回给浏览器端。后续请求均如此
  • 第六步,这时用户需要在同一个浏览器中访问应用2中的资源2,第一次访问应用2一般会在请求中包含一个特殊的字符(例如:sso),用于标识这不是通过用户名密码登录在后台维护的登录态,而是单点登录的请求。前端js识别到这个URL后,会首先向认证中心发送一个请求,自动携带认证中心的sessionid-auth,询问认证中心,这个sessionid对应的用户是不是在别的应用登录过,如果有,你给我返回一个authcode。认证中心查询自己的分布式缓存,发现有这个sessionid对应的用户信息,于是产生了一个authcode返回浏览器端
  • 第七步,浏览器拿到认证中心返回的authcode后,在请求应用2的登录服务2,告诉他,你看我从认证中心获取到了一个authcode,你给我换成具体的用户信息吧。登录服务2根据这个auth code去请求认证中心,认证中心返回用户名、token等用户信息。登录服务2在自己的分布式缓存中同样维护一份登录状态和用户信息,同时向前端Cookie中设置应用2的sessionid2
  • 第八步,单点登录成功后,重定向至应用2的资源2,逻辑同第四步
  • 第九步,浏览器继续请求下一个应用2的资源数据,逻辑同第五步