登录

mikechen的技术专栏

故  事
合  集

    HTTP协议格式详解

    mikechen的技术专栏
    2024-03-10
    来源: HTTP协议格式详解 - 简书

    字节一面:HTTPS 会加密 URL 吗?

    mikechen的技术专栏
    2024-03-10
    来源: 字节一面:HTTPS 会加密 URL 吗?-https url 加密

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

    Ken 2017-11-25 15:32:53

    一、前言

    1、SSO说明

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

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

    • 网易直播 http://v.163.com
    • 网易博客 http://blog.163.com
    • 网易花田 http://love.163.com
    • 网易考拉 https://www.kaola.com
    • 网易Lofter http://www.lofter.com

    2、设计目标

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

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

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

    二、SSO设计与实现

    1、核心应用与依赖

    单点登录(SSO)设计

    应用/模块/对象 说明
    前台站点 需要登录的站点
    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、用户登录/登录校验

    • 登录时序图

    SSO系统设计-登录时序图

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

    • 登录信息获取/登录状态校验

    SSO系统设计-登录信息获取/登录状态校验

    4、用户登出

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

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

    SSO系统设计-用户登出

    5、跨域登录、登出

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

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

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

    • 跨域登录(主域名已登录)

    SSO系统设计-跨域登录(主域名已登录)

    • 跨域登录(主域名未登录)

    SSO系统设计-跨域登录(主域名未登录)

    • 跨域登出

    SSO系统设计-跨域登出

    三、备注

    • 关于方案

    这次设计方案更多是提供实现思路。如果涉及到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


    Ken的杂谈

    本文由 ken.io 创作,采用CC BY 3.0 CN协议 进行许可。 可自由转载、引用、甚至修改,但需署名作者且注明出处。

    mikechen的技术专栏
    2024-03-10
    来源: 单点登录(SSO)的设计与实现 - Ken的杂谈

    单点登录SSO的实现原理与方案详解

    mikechen

    单点登录SSO的实现原理与方案详解-mikechen

    为什么需要单点登录

    单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。

    单点登录在大型网站里使用得非常频繁,例如,阿里旗下有淘宝、天猫等网站,还有背后的成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉。

    单点登录SSO的实现原理与方案详解-mikechen

    所以,单点登录要解决的就是,用户只需要登录一次就可以访问所有相互信任的应用系统。

    单点登录的来源

    1.早期web单系统应用

    早期我们开发web应用都是所有的包放在一起打成一个war包放入tomcat容器来运行的,所有的功能,所有的业务,后台管理,门户界面,都是由这一个war来支持的,这样的单应用,也称之为巨石应用,因为十分不好扩展和拆分。

    在巨石应用下,用户的登录以及权限就显得十分简单,当浏览器向服务器发送登录请求时,验证通过之后,会将用户信息存入seesion中,然后服务器会生成一个sessionId放入cookie中,随后返回给浏览器。

    大致可以用下图来表示:

    单点登录SSO的实现原理与方案详解-mikechen

    验证登录的这个会话就是session,维护了用户状态,也就是所谓的HTTP有状态协议,我们经常可以在浏览器中看到JSESSIONID,这个就是用来维持这个关系的key。
    单点登录SSO的实现原理与方案详解-mikechen

    2.分布式集群部署

    由于网站的访问量越来也大,单机部署已经是巨大瓶颈,所以才有了后来的分布式集群部署。

    例如:如果引入集群的概念,单应用可能重新部署在3台tomcat以上服务器,使用nginx来实现反向代理。

    但是增加新的服务器之后,不同的服务器之间的sessionId是不一样的,可能在A服务器上已经登录成功了,能从服务器的session中获取用户信息,但是在B服务器上却查不到session信息,只好退出来继续登录,结果A服务器中的session因为超时失效,登录之后又被强制退出来要求重新登录。

    单点登录SSO的实现原理与方案详解-mikechen

    所以不得不考虑多服务器之间的session数据一致的问题,这就是单点登录的最早来源。

    单点登录的实现方式

    单点登录的本质就是在多个应用系统中共享登录状态,如果用户的登录状态是记录在 Session 中的,要实现共享登录状态,就要先共享 Session。

    所以实现单点登录的关键在于,如何让 Session ID(或 Token)在多个域中共享。

    1.同域下的单点登录

    一个企业一般情况下只有一个域名,通过二级域名区分不同的系统。

    比如我有个域名:mikechen.cc,同时有两个业务系统分别为:

    1. blog.mikechen.cc
    2. video.mikechen.cc

    我们要做单点登录(SSO),需要一个登录系统,叫做:sso.mikechen.cc。

    我们只要在sso.mikechen.cc登录,blog.mikechen.cc和video.mikechen.cc也登录了。

    实现方式:其实这里就是利用了 二级域名 写 一级域名的 Cookie 。sso.mikechen.cc登录以后,可以将Cookie的域设置为顶域,即.mikechen.cc,这样所有子域blog.mikechen.cc和video.mikechen.cc的系统都可以访问到顶域的Cookie。

    此种实现方式比较简单,但不支持跨主域名,局限性限于一级域名是一样的。

    2.不同域下的单点登录

    同域下的单点登录是巧用了Cookie顶域的特性,如果是不同域呢,比如:下面三个是不同域的

    1. mikechen1.cc
    2. mikechen2.cc
    3. mikechen3.cc

    实现方式:我们可以部署一个SSO认证中心,认证中心就是一个专门负责处理登录请求。

    单点登录SSO的实现原理与方案详解-mikechen

    所有的请求(登录、退出、获取用户信息、当前用户状态)都请求sso 系统,sso 系统维护用户信息。

    此种实现方式相对复杂,支持跨域,扩展性好,是单点登录的标准做法。

    基于SSO认证中心的开源项目代表:CAS,其中 CAS是Central Authentication Service,即中央认证服务,下图是CAS的基本过程:

    单点登录SSO的实现原理与方案详解-mikechen

    以上就是基于单点登录的介绍!

    作者简介

    陈睿|mikechen,10年+大厂架构经验,大厂资深面试官,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

    👇阅读更多mikechen架构文章👇

    阿里架构 |双11秒杀 |分布式架构 |负载均衡 |单点登录 |微服务 |云原生 |高并发 |架构师

    以上

    关注作者「mikechen」公众号,获取更多技术干货!

    mikechen的技术专栏
    2024-03-10
    来源: 单点登录SSO的实现原理与方案详解 – mikechen
该操作需要登录!
请先验证Email!
Success! 创建成功