单点登录(SSO)的设计与实现

一、前言

什么是SSO?

SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。https://baike.baidu.com/item/SSO/3451380

例如访问在网易账号中心(http://reg.163.com/ )登录之后 访问以下站点都是登录状态

本次设计目标

本篇文章也主要是为了探讨如何设计&实现一个SSO系统

以下为需要实现的核心功能:

  • 单点登录
  • 单点登出
  • 支持跨域单点登录
  • 支持跨域单点登出

二、SSO设计与实现

1、核心应用&依赖

应用/模块/对象

说明

前台站点

需要登录的站点

SSO站点-登录

提供登录的页面

SSO站点-登出

提供注销登录的入口

SSO服务-登录

提供登录服务

SSO服务-登录状态

提供登录状态校验/登录信息查询的服务

SSO服务-登出

提供用户注销登录的服务

数据库

存储用户账户信息

缓存

存储用户的登录信息,通常使用Redis

2、用户登录状态的存储&校验逻辑

常见的Web框架对于Session的实现都是生成一个SessionId存储在浏览器Cookie中。然后将Session内容存储在服务器端内存中,这个 ken.io 在之前Session工作原理中也提到过。整体也是借鉴这个思路。 用户登录成功之后,生成AuthToken交给客户端保存。如果是浏览器,就保存在Cookie中。如果是手机App就保存在App本地缓存中。本篇主要探讨基于Web站点的SSO。 用户在浏览需要登录的页面时,客户端将AuthToken提交给SSO服务校验登录状态/获取用户登录信息

对于登录信息的存储,建议采用Redis,使用Redis集群来存储登录信息,既可以保证高可用,又可以线性扩充。同时也可以让SSO服务满足负载均衡/可伸缩的需求。

对象

说明

AuthToken

直接使用UUID/GUID即可,如果有验证AuthToken合法性需求,可以将UserName+时间戳加密生成,服务端解密之后验证合法性

登录信息

通常是将UserId,UserName缓存起来

3、用户登录/登录校验
  • 登录时序图

按照上图,用户登录后Authtoken保存在Cookie中。 domian= test. com 浏览器会将domain设置成 .test.com, 这样访问所有*.test.com的web站点,都会将Authtoken携带到服务器端。 然后通过SSO服务,完成对用户状态的校验/用户登录信息的获取

  • 登录信息获取/登录状态校验
4、用户登出

用户登出时要做的事情很简单:

  1. 服务端清除缓存(Redis)中的登录状态
  2. 客户端清除存储的AuthToken
  • 登出时序图

5、跨域登录、登出

前面提到过,核心思路是客户端存储AuthToken,服务器端通过Redis存储登录信息。由于客户端是将AuthToken存储在Cookie中的。所以跨域要解决的问题,就是如何解决Cookie的跨域读写问题。

解决跨域的核心思路就是:

  • 登录完成之后通过回调的方式,将AuthToken传递给主域名之外的站点,该站点自行将AuthToken保存在当前域下的Cookie中。
  • 登出完成之后通过回调的方式,调用非主域名站点的登出页面,完成设置Cookie中的AuthToken过期的操作。
  • 跨域登录(主域名已登录)
  • 跨域登录(主域名未登录)
  • 跨域登出

三、备注

  • 关于方案

这次设计方案更多是提供实现思路。如果涉及到APP用户登录等情况,在访问SSO服务时,增加对APP的签名验证就好了。当然,如果有无线网关,验证签名不是问题。

  • 关于时序图

时序图中并没有包含所有场景,ken.io只列举了核心/主要场景,另外对于一些不影响理解思路的消息能省就省了。

  • 前置知识

1、Session的工作原理和使用经验:https://ken.io/note/session-principle-skill 2、Cookie的特点和使用经验/建议总结:https://ken.io/note/cookie-feature-skill

以上,如有疑问,欢迎联系我:https://ken.io/home/about

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏玩转JavaEE

Redis集群搭建

1.所有的Redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽 2.节点的fail是通过集群中超过半数的节点检测失效时才生效 ...

2120
来自专栏蛋未明的专栏

网页实现批量数据导入功能

1962
来自专栏开源优测

Linux下常用的监控工具和命令

如果性能测试的目标服务器是linux系统,在如何使用linux自带的命令来实现性能测试过程的监控分析呢?

1432
来自专栏会跳舞的机器人

Nginx+Tomcat实现负载均衡

在103和117上分别部署相同的Tomcat程序,修改index.jsp页面,把内容改为各自的IP地址。

1243
来自专栏北京马哥教育

给小白的 Nginx 30分钟入门指南

运维行业正在变革,推荐阅读:30万年薪Linux运维工程师成长魔法 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服...

4347
来自专栏Java成长之路

解决session共享问题方式调研

为了提高服务器性能,最近公司项目采用了分布式服务集群的部署方式。所谓集群,就是让一组计算机服务器协同工作,解决大并发,大数据量瓶颈问题。项目使用nginx做负载...

1871
来自专栏李观玉的专栏

【腾讯云的1001种玩法】xmpp开源服务器的配置和安装图文详解

今天,我和同学一起开发一个软件的时候,想弄一个xmpp开源服务器来实现我们软件的通讯聊天,但是由于网上教程的不够详细和大部分教程都是转账同一个博客的博文,这样对...

4520
来自专栏小程序之家

如何实现小程序登录鉴权

为了方便用户使用小程序时,使用微信账号授权快速登录软件,微信小程序提供了相关的授权接口。小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快...

1.8K5
来自专栏GreenLeaves

Oracle 事务操作

在看本文之前,请确保你已经了解了Oracle事务和锁的概念即其作用,不过不了解,请参考数据库事务的一致性和原子性浅析和Oracle TM锁和TX锁 1、提交事务...

2566
来自专栏blackheart的专栏

[OIDC in Action] 2. 基于OIDC(OpenID Connect)的SSO(纯JS客户端)

在上一篇基于OIDC的SSO的中涉及到了4个Web站点: oidc-server.dev:利用oidc实现的统一认证和授权中心,SSO站点。 oidc-clie...

3178

扫码关注云+社区

领取腾讯云代金券