通过Cookie 实现基于Session 的SSO

43 篇文章 0 订阅

缘起

  • 简称SSO,在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的其它应用系统
  • 应用场景 同一家公司的不同子系统之间的登录认证
  • 单点登录实现方式
    • 基于cookie凭证
      • 适用子系统之间主域名一致,如此这般才能让不同子系统之间共享Cookie
    • 通过CAS实现SSO系统
      • 该方案适用于所有场景

实现思路

  • 场景需求
    • 不同子系统之间是分离的,域名也不一样,比如主系统是 blog.test,子系统是 sub.blog.test
    • Laravel 添加 Cookie 到响应时默认作用域名是当前系统域名
  • 对写入 Cookie 的域名做额外设置,保证主系统和子系统之间可以共享 Cookie 凭证
  • 子系统和主系统之间共享用户表,子系统中不需要再设置独立的用户表
  • 子系统获取用户信息时通过 API 从主系统获取,需要实现 UserProvider 以便获取用户信息
  • 关键问题
    • Cookie是不能跨域传递的,将一个域的Cookie通知给其它应用(不在同一个域)

解决方案

  • 共享Cookie

    • Cookie种在父域下,浏览器同域名下的Cookie则可以共享
    • 因此可以通过Cookie加解密的算法获取用户SessionID,从而实现SSO
  • 问题

    • 所有同域名的系统都能获取SessionID,易被修改且不安全
    • 跨域无法使用
  • ticket验证

    1. 用户访问某个子系统,发现如果未登录,则引导用户跳转到SSO登录页面
    2. 判断SSO是否已经登录
    3. 如果已经登录,直接跳转到回调地址,并返回认证ticket
    4. 如果未登录,用户正确输入用户名/密码,认证通过跳转到回调地址,并返回认证ticket
    5. 子系统获取ticket,调用SSO获取用户uid等信息,成功后让用户登录
  • cookie domain

    • Http协议在响应头部,可用Set-Cookie中的domain字段用来表示这个cookie所在的域
    • 设置cookie的父域名(domain),客户端访问子域,能够把设置的cookie返回
    • 涉及登录凭证(如票据或者用户名)应该加密,cookie不能存放隐私数据
    • 通过特殊设置setDomain()可以做到跨同一个大域下的两个子域
焦点
  • 高效存储大量临时性的信任数据
  • 防止信息传递过程被篡改
  • 让SSO系统信任登录系统和免登系统
解决措施
  • 采用类似与memcached的分布式缓存的方案,既能提供可扩展数据量的机制,也能提供高效访问
  • 采取数字签名的方法,要么通过数字证书签名,要么通过像md5的方式
  • 通过白名单来处理,生产信任关系

登录中心Cookie设置

  • 单点登录需要一个独立的登录中心,所有系统登录皆从此入,通常将主系统作为登录中心
  • 设置Cookie域名
    • 设置主系统Cookie作用域名
    • 登录成功后,通过 CreateFreshApiToken中间件将令牌,SessionID写入到Cookie
    • 在子系统中可读取上述Cookie,并在请求头中带上

流程

  • Cookie 域名通过 config/session.php 中的配置项 domain 来实现

  • 添加 CreateFreshApiToken 中间件(该中间件需要事先安装过 Passport)

  • 在 routes/api.php 中新增一条路由,返回认证用户信息

  • 设置Session存储媒介

    • 基于 Session 实现的单点登录,我们还要让主系统和子系统共享用户 Session 信息
    • 在登录中心(主系统)安装 predis 扩展 composer require predis/predis
  • 在子系统自定义 UserProvider 实现

    • 子系统项目,自定义一个 UserProvider实现来从主系统获取认证用户信息
      • 通过GuzzleHttp库请求,重写 retrieveById方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值