作者:来自 vivo 互联网服务器团队- Wang Fei

单点登录作为公共组件,在各个公司内部被各个系统所广泛使用,但是在使用过程中我们会遇到各种各样的问题,其中循环登录问题就是一个比较经典的问题。本文主要分析单点登录和权限系统设计的基本原理,然后结合实际案例来分析循环登录的原因,并给出具体的解决办法。

一、单点登录简单介绍

1.1 基本概念

一个公司内部可能存在多个系统,如果每一个人在使用不同系统的时候都需要重新登录,那么会做大量系统登录切换、耗费比较多的精力去管理账号和密码,那么有没有办法在一个公司内部的所有系统只需要一次登录验证,后续使用其他系统的时候不用重复登录就可以直接使用呢,这就是单点登录要解决的问题。

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

1.2 基本实现原理

  • 用户登录:用户在任何一个应用程序或系统中进行身份验证,并提供他们的凭据。
  • 认证系统验证:该凭据被发送到认证系统进行验证。如果凭据有效,则认证系统会为用户生成数字签名的令牌(如 Token 或 Ticket)。
  • 令牌分发:认证系统将令牌返回给应用程序或子系统。
  • 应用程序或系统授权:应用程序或系统使用令牌验证用户的身份,并授权其访问相应资源或服务。
  • 跨域系统访问:用户可以通过同一令牌访问多个跨域应用程序或系统,而无需重复进行身份验证。

二、循环登录问题

在某一天我们登录一个内部系统时,突然出现了循环登录问题,前端页面不断刷新,提示“重定向次数过多问题”。

打开前端调试功能, 我们会发现确实存在大量重定向请求的问题:

那么平时登录没问题的系统为什么突然间就循环登录呢?并在页面上提示的解决方法“尝试删除您的 Cookie 操作”,按照这个操作以后,确实系统又可以跳转到登录页面正常进行登录了,这又是什么原因?下面我们将逐一分析。

三、从一次正常登录流程说起

上述是一个通用的系统权限管控和单点系统认证的标准流程:

  • 用户第一次访问时,在浏览器输入 https://aaa.x.y  回车
  • 权限系统进行拦截,判断用户是否登录,这里主要是通过是否有登录信息判断,如果没有登录,权限系统会帮我们跳转到单点登录系统,弹出用户登录页。
  • 用户填写用户名、密码,单点登录系统进行认证后,将登录状态写入 SSO 的 session。
  • SSO 系统登录完成后会给我们的系统生成一个 Token ,然后跳转到我们的系统,同时将 Token 作为参数传递给我们的系统。
  • 我们系统拿到 Token 后,从后台向 SSO 发送请求,验证 Token 是否有效。
  • 验证通过后,我们系统将记录顶级域下的 Cookie 信息。
Connection: keep-alive
Content-Length: 0
Date: Wed, 25 Oct 2023 08:29:43 GMT
Location: http://aaa.x.y/console/login/auth?redirectUrl=http://aaa.x.y/
optrace: xx.xx.xx.xx:80/302 <- -
Server: nginx
Set-Cookie: token=fakdfajdfdjfdjkfaldfjk'afafjasfasfa; Max-Age=86400; Expires=Thu, 26-Oct-2023 08:29:43 GMT; Domain=x.y; Path=/; HttpOnly

一个公司内部一般情况下只有一个域名,通过二级域名区分不同的系统。比如我们有个域名叫做:x.y ,同时有两个业务系统分别为:app1.x.y 和 app2.x.y。SSO 登录以后,可以将 Cookie 的域设置为顶域,即 x.y ,这样所有子域的系统都可以访问到顶域的 Cookie ,实现单点登录功能。

四、循环登录产生的根本原因

那么为什么会不断循环登录呢?

(1)从跳转记录来看,我们发现重新刷新页面以后,重定向到了权限系统,并且 Request Headers 中的 Cookie 信息没有传对应的 Token 信息。

(2)跳转到权限系统过后,再跳转到本系统的时候,已经获取到了对应的 Token 信息,但是在 Set-Cookie 信息的时候,出现了一个警告。

警告的具体内容为:

大致意思是:这次执行 Set-Cookie 操作被阻止了,原因是这个 Cookie 不是通过安全的连接进行传输的,我们这次访问确实使用了 HTTP 进行,本应该通过设置   Secure 属性来覆盖对应的 Cookie。

这里的 Secure 属性是 Cookie 的一个属性,Secure 属性是说如果一个 Cookie 被设置了 Secure = true,那么这个 Cookie 只能用 HTTPS 协议发送给服务器,用 HTTP 协议是不发送的,而我们查看上面标注位置的下一个 Login 请求确实没有传 Cookie 信息,从而继续进行用户是否登录校验,进入死循环过程, 可以看下面的示意图:

五、清除浏览器缓存的底层原理及解决方法

5.1 清除浏览器缓存的底层原理

我们可以看到循环登录以后,会在浏览器页面上提示 xxx.x.y 重定向次数过多,尝试清除 Cookie 信息,那清除 Cookie 信息以后,是不是真的就可以解决这个问题呢,我们尝试着清除浏览器缓存,确实可以解决这个问题,那清除浏览器缓存来解决循环登录问题的底层原理是什么呢,其实质就是将 Cookie 删除,其他域名设置 Cookie 上的 Secure 属性也就一并删除了,从而使用 HTTP 域名进入重新登录流程,可以正常设置 Cookie 信息。

5.2 其他解决办法

方法一:使用 HTTPS 的方式进行访问
现实使用中,我们无法控制其他 HTTPS 访问的具有相同顶级域名的服务不去设置 Cookie 的 Secure 属性,因而我们在后面使用的过程中还是会遇到这个问题,那么有没有一种彻底的解决办法能够避免这个问题再次出现,我们前面已经分析,之所以我们在开始使用 HTTP 能够进行正常访问,然后突然间不能正常访问了,就是因为已经被 HTTPS 设置了的 Cookie 信息是无法被 HTTP 重新设置的,从而拿不到 Cookie 信息。那么就出现了第一种解决办法,使用 HTTPS 的方式进行访问,即使其他服务设置了 Cookie 的 Secure 属性,用 HTTPS 仍然能够成功设置 Cookie 和获取 Cookie。

方法二:在 Cookie 信息中新设置一个 newToken
以上从 HTTP 转为 HTTPS 访问的方法在用户主动找我们反馈时是能够告诉它切换为 HTTPS 访问的,但是如果对于一些没有主动找我们反馈的用户,其实是无法解决,可能丧失这个用户造成用户流失的情况,那么我们在用户不进行切换的情况下是否能够解决这个问题。

同一个公司内部接入的权限系统是一种底层公共能力,为了保证单点登录,其实用户信息的读取都是通过同一个 Cookie 参数(比如叫 Token )读取的,那么在其他域名设置了公共 Cookie 参数的 Secure 属性而影响到 HTTP 登录的时候,我们可以给服务新增加一个 Cookie 参数 newToken 去解决。

六、扩展: Cookie 的端口不隔离性

本文所阐述的问题,出现的背景是有两个基本前提的:一是为了保证单点登录,两个域名属于同一个顶级域名,权限系统中关于用户信息的校验都是通过同一个 Cookie 属性去读取的;第二个是 HTTPS 设置了顶级域名的 Cookie 信息的 Secure 属性,然后使用 HTTP 访问会导致循环登录。有些开发者可能会有这样一个疑问,那就是 HTTPS 我们一般开通的端口是 443 , HTTP 我们一般开通的端口是 8080 ,为啥不从端口上进行区分同一个 Cookie 属性从而避免干扰呢?

这个在 Cookie 规范(RFC 6265)中有所描述,那就是 Cookie 不提供通过端口进行隔离的,也就是说如果一个 Cookie 可以被一台服务器上的运行在某一个端口上的一个服务所读取,那么也可以被这台服务器上运行在另外一个端口上的服务所读取;如果一个 Cookie 可以被一台服务器上的运行在某一个端口上的一个服务所写入,那么也可以被这台服务器上运行在另外一个端口上的服务所写入。

七、总结

本文从实际开发过程中遇到的循环登录问题入手,分析了由于设置 Secure 属性导致使用 HTTP 访问网页无法保存 Cookie 信息从而导致循环登录的根本原因,也给出了其他两个解决此种问题的方案,对于其他开发人员解决权限系统循环登录问题具有一定的借鉴意义。

参考资料:

单点登录实现思路及方案
Sessions don't work in Chrome but do in IE
8.5. Weak Confidentiality

Cookie的secure属性引起循环登录问题分析及解决方案的更多相关文章

  1. Cookie的Secure属性

    基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie ...

  2. Cookie的Secure属性和HttpOnly属性

    基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie ...

  3. 一次cookie引起系统不断要求重新登录问题分析

    我们的产品里有一配置服务(tomcat),采用ajax来通信交互 但是最近频频发现登录后马上弹出要重新登录的情况,一开始以为是cookie没有带上导致session找不到,后来问题依旧,查看浏览器co ...

  4. IBM AppScan 安全扫描:加密会话(SSL)Cookie 中缺少 Secure 属性 处理办法 分类: 数据安全 2014-06-28 11:35 2805人阅读 评论(0) 收藏

    问题描述: 原因分析: 服务器开启了Https时,cookie的Secure属性应设为true:   解决办法: 1.服务器配置Https SSL方式,参考:https://support.micro ...

  5. Appscan漏洞 之 加密会话(SSL)Cookie 中缺少 Secure 属性

    近期 Appscan扫描出漏洞 加密会话(SSL)Cookie 中缺少 Secure 属性,已做修复,现进行总结如下: 1.1.攻击原理 任何以明文形式发送到服务器的 cookie.会话令牌或用户凭证 ...

  6. Session Cookie的HttpOnly和secure属性

    Session Cookie的HttpOnly和secure属性 一.属性说明: 1 secure属性 当设置为true时,表示创建的 Cookie 会被以安全的形式向服务器传输,也就是只能在 HTT ...

  7. Cookie中设置了 HttpOnly,Secure 属性,有效的防止XSS攻击,X-Frame-Options 响应头避免点击劫持

    属性介绍: 1) secure属性当设置为true时,表示创建的 Cookie 会被以安全的形式向服务器传输(ssl),即 只能在 HTTPS 连接中被浏览器传递到服务器端进行会话验证, 如果是 HT ...

  8. Http中Cookie的HttpOnly和secure属性

    Cookie语法: Cookie通常是作为HTTP 应答头发送给客户端的,下面的例子展示了相应的语法(注意,HttpOnly属性对大小写不敏感):  Set-Cookie: =[; =]   [; e ...

  9. cookie的secure、httponly属性设置

    cookie的secure.httponly属性设置 转载自:http://www.cnblogs.com/alanzyy/archive/2011/10/14/2212484.html 一.属性说明 ...

  10. cookie 的HttpOnly 和 Secure 属性

    设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie打出cookie的内容. Secure属性是说如果一个cookie被设置了Secure=true,那么 ...

随机推荐

  1. mac idea 配置Tomcat

    官网下载Tomcat 下载地址:点我直达 配置Idea 设置Application Servers 操作步骤:Intellij IDEA->Preferences->Application ...

  2. 1. CMake 概述

    1. CMake 概述 CMake 可以用来构建C/C++工程,可以跨平台.允许开发者指定整个工程的编译流程 在CMake 没有出来之前,开发者需要手写 makefile,但是不同平台下的 makef ...

  3. 内部网关协议RIP

    RIP协议的特点:仅和相邻路由器交换信息:交换自己现在的路由表:按固定的时间周期. 对每一个相邻路由器发送的RIP报文,执行以下步骤: 1.对地址为x的相邻路由器发来的报文,修改此报文中的所有项目,把 ...

  4. django python 循环一个月的每一天

    from datetime import datetime, timedelta def get_dates_in_month(year, month): start_date = datetime( ...

  5. 基于Java:流浪动物领养信息系统设计实现(源码+lw+部署文档+讲解等)

    \n文末获取源码联系 感兴趣的可以先收藏起来,大家在毕设选题,项目以及论文编写等相关问题都可以给我加好友咨询 系统介绍: 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件 ...

  6. 变频器通过Modbus转Profinet网关接电机与PLC通讯在自动化的应用

    巴图自动化Profinet转Modbus模块(BT-MDPN10)是一种用于不同通讯协议之间互连的设备,它可以将Profinet与Modbus这两种不同的通讯协议进行转换,从而实现设备之间的通讯和数据 ...

  7. [oeasy]python0101_尾声_PC_wintel_8080_诸神的黄昏_arm_riscv

    尾声 回忆上次内容 回顾了 ibm 使用开放架构 用 pc兼容机 战胜了 dec 小型机 apple 个人电脑 触击牺牲打 也破掉了 自己 软硬一体全自主的 金身 借助了 各种 软硬件厂商的 力量 最 ...

  8. [rCore学习笔记 08]内核第一条指令

    了解QEMU 启动指令 qemu-system-riscv64 \ -machine virt \ -nographic \ -bios ../bootloader/rustsbi-qemu.bin ...

  9. C练习_1005

    题自:题目 1009: [编程入门]数字的处理与判断_C语言网 题目描述 给出一个不多于5位的整数,要求 1.求出它是几位数 2.分别输出每一位数字 3.按逆序输出各位数字,例如原数为321,应输出1 ...

  10. selenium启动Chrome配置参数问题

    每次当selenium启动chrome浏览器的时候,chrome浏览器很干净,没有插件.没有收藏.没有历史记录,这是因为selenium在启动chrome时为了保证最快的运行效率,启动了一个裸浏览器, ...