iframe页面二次登录问题
原文链接:iframe页面二次登录问题
生产问题
问题背景
由于历史原因,公司内部系统有一些页面是基于iframe嵌入的其他系统的页面,之前一直运行正常,最近不知什么原因接连出现访问所有iframe页面时提示需要登录的情况,并且点击iframe页面的登录按钮时会出现页面闪一下,没有任何跳转的现象。

问题显而易见,怎么解决呢?透过现象看本质,旁边业务还在催问什么时候能恢复,只能硬着头皮一步步分析着看。

首先,这些系统都接入了公司内部的sso服务,主体系统A已经成功登录的情况下,内嵌系统B还需要二次登录,肯定是相关鉴权未通过。
而整个鉴权信息都是基于Cookie机制来完成的,所以借此机会先回顾一下Cookie相关知识。
原因定位
跟踪网络请求发现,当请求内嵌页面时,首先会发起SSO认证请求https://sso.xxx.com/authentication/login?sevice=http://b.xxx.com,这个请求的scheme是HTTPS,而主系统A没有升级HTTPS, 所以B系统发起SSO认证时属于cross-site情形,无法携带此前生成的用户身份Cookie信息,用户鉴权失败。


当点击内嵌页面中的登录按钮时,由于此时发起的请求仍然是cross-site的,所以Cookie始终无法写入,就会出现页面闪一下,但并未登录的情况。

Cookie
HTTP Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器发起请求时被携带并发送到服务器上。
Cookie主要用于以下三个方面:
- 会话状态管理,如用户登录状态、购物车、游戏分数等。
- 个性化设置,如用户自定义设置,主题等。
- 浏览器行为跟踪,如跟踪分析用户行为等。
第三方Cookie
Cookie与域关联。如果此域与您所在页面的域相同,则该Cookie称为第一方Cookie(first-party cookie)。如果域不同,则它是第三方Cookie(thirty-patry cookie)。第三方Cookie是由第三方网站引导发出的,可以用于CSRF攻击以及用户行为追踪。
限制访问Cookie
通过以下方式可以确保Cookie被安全发送,不会被意外的参与者或脚本访问:
Secure属性:标记为Secure的Cookie只能通过被HTTPS协议加密过的请求发送给服务端,可以借此来预防中间人攻击从 Chrome 52 和 Firefox 52 开始,不安全的站点(
http:)无法使用Cookie的Secure标记。HttpOnly属性:JavaScript的Document.cookieAPI无法访问带有HttpOnly属性的Cookie,此类Cookie仅作用于服务器。例如,持久化服务器会话的Cookie不需要对JavaScript可用,因此可以设置HttpOnly属性。可以借此来缓解XSS攻击。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
Cookie作用域
通过Domain和Path标识来定义Cookie的作用域:即允许Cookie应该发送给哪些URL。
Domain属性
指定哪些主机可以接受Cookie。默认为origin,不包含子域名。如果指定了Domain,则一般包含子域名。
当前大多数浏览器遵循 RFC 6265,设置 Domain 时 不需要加前导点。浏览器不遵循该规范,则需要加前导点,例如:Domain=.mozilla.org
Path属性
指定主机下哪些路径可以接受Cookie(该URL路径必须存在于请求URL中)。以字符%X2F("/")作为路径分隔符,子路径也会被匹配。
例如,设置Path=/docs,以下地址都会匹配:
- /docs
- /docs/web/
- /docs/web/HTTP
SameSite属性
SameSite属性允许服务器要求某个Cookie在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。
Set-Cookie: key=value; SameSite=Strict
SameSite取值有以下三种:
None:浏览器会在同站请求、跨站请求下继续发送Cookie,不区分大小写。大多数网站已经将
SameSite的默认值设置为Lax,此时如果网站想要关闭SameSite属性,必须在将SameSite属性设置为None的同时设置Secure属性,否则无效。
// 该设置无效
Set-Cookie: widget_session=abc123; SameSite=None
// 有效设置
Set-Cookie: widget_session=abc123; SameSite=None; Secure
Strict浏览器只在访问相同站点时发送Cookie。Lax:与Strict类似,但用户从外部站点导航至目标网址的Get请求除外(链接、预加载请求以及GET表单)。
| 请求类型 | 示例 | 正常情况 | Lax |
|---|---|---|---|
| 链接 | <a href="..."></a> |
发送 Cookie | 发送 Cookie |
| 预加载 | <link rel="prerender" href="..."/> |
发送 Cookie | 发送 Cookie |
| GET 表单 | <form method="GET" action="..."> |
发送 Cookie | 发送 Cookie |
| POST 表单 | <form method="POST" action="..."> |
发送 Cookie | 不发送 |
| iframe | <iframe src="..."></iframe> |
发送 Cookie | 不发送 |
| AJAX | $.get("...") |
发送 Cookie | 不发送 |
| Image | <img src="..."> |
发送 Cookie | 不发送 |
same-origin和same-site
同源(same-origin)、同站点(same-site)是两个随处可见的概念,但是这两个概念经常容易被混淆。
Origin
首先来看一下origin的定义是什么。scheme + hostname + port构成的整体叫做origin,例如https://www.example.com/443/foo的origin是https://www.example.com/443。

具有相同的scheme、hostname以及port的站点被视为同源站点,否则视为跨域(cross-origin)站点.
Site
学习site之前,先来了解一下什么是TLD、eTLD。
TLD
TLD全称叫做顶级域名(Top-Level-Domain),比如我们经常看到的com、cn、io之类的,都属于顶级域名。
TLD有一个记录列表,这个列表叫做Root Zone Database,里面记录了所有的顶级域名。需要注意的是,顶级域名不一定都是单词很短且只有一级的域名。

如上图,TLD和它之前部分的域构成的整体叫做"site",比如https://www.example.com:443/foo ,"site" 是example.com。
eTLD
除了顶级域名之外,还有一种叫做eTLD(effective Top-Level-Domain)的东西,它表示的是有效顶级域名。
例如.io是一个TLD,而像.github.io,是一个开放给用户的用于搭建个人网站的一个域。比如现在有以下三个网站:
http://zhangsan.github.io
http://lisi.github.io
http://wangwu.github.io
我们判断是否是同一个站点,通常是采用顶级域名+二级域名来判断,这里如果直接用.io这个TLD来识别,就会认为这三个网站是同一个站点,Cookie可以共享。
显然这是有问题的,因此需要引入eTLD的概念,将.io与github合起来的.github.io注册为一个"effective TLDs"。将eTLD+1整体视为网站的站点名称,这样一来,上述三个网址表示的就是不同的网站,Cookie就会相互隔离。

eTLD信息在Public Suffix List列表中定义,可以通过publicsuffix.org/list查询域名是否为有效顶级域名。
schemeful same-site
关于"same-site的定义一直在不断演变,由此出现将URL Scheme看作是site的一部分的这种策略。基于这种策略可以避免网站遭受基于HTTP协议的一些攻击。
在schemeful same-site规则下,由于scheme不同,http://www.example.com 和https://www.example.com 被认为是不同的站点。
如何判断
Chrome浏览器发送请求时会携带名为Sec-Fetch-Site的Header信息,根据该Header的取值可以判断当前请求是否同源、是否跨站(schemeful-same-site未被记录在Sec-Fetch-Site中)。

Sec-Fetch-Site取值如下:
cross-sitesame-sitesame-originnone
欢迎关注我的微信公众号:【高高木】。第一时间阅读最新经验分享,一起交流成长。
iframe页面二次登录问题的更多相关文章
- iframe页面总是提示需要重新登录怎么办
原文链接:iframe页面二次登录问题 生产问题 问题背景 由于历史原因,公司内部系统有一些页面是基于iframe嵌入的其他系统的页面,之前一直运行正常,最近不知什么原因接连出现访问所有iframe页 ...
- Asp.net MVC访问框架页中嵌套的iframe页面时,如果session或cookie过期,登录验证超时怎样自动跳转到登录页
一般登录验证的过滤器中,使用验证过滤器的Redirect方法,将请求重定向到指定的URL.但是如果我们要访问的页面是一个嵌套在框架页中的iframe页面时,这种重定向只会对iframe页面凑效,也就是 ...
- lhgdialog: iframe页面里面的,确定,关闭、取消按钮的操作
lhgdialog: iframe页面里面的,确定,关闭.取消按钮的操作 如果你正在用lhgdialog,用他人iframe,或者 content:'url:http://www.baidu.com/ ...
- 新闻cms管理系统(二) ---- 后台登录功能
1.页面准备: (1)前端资源的导入:将准备好的页面添加到项目中,放到Public目录下(公共的页面样式.js.图片等资源) (2)添加登录的视图模板 将登录页面的视图放到Amin>View&g ...
- js 获取iframe页面元素
js 获取iframe页面元素 CreationTime--2018年8月16日18点00分 Author:Marydon <!-- chart图表 --> <iframe id ...
- amazeui页面分析之登录页面
amazeui页面分析之登录页面 一.总结 1.tpl命名空间:tpl命名空间的样式都是从app.css里面来的,app.css用用来移动网站开发的样式 2.表单样式:am-form到am-form- ...
- 公众号H5页面接入微信登录流程
公众号H5页面接入微信登录流程 源码地址 https://gitee.com/szxio/h5_weixin 起步 首先创建一个项目,我们采用uni-app来作为我们的前端框架 环境安装 全局安装vu ...
- layer.open打开iframe页面的调用父页面方法及关闭
//调用父类方法 window.parent.exportData($('#shownum').val(),$('#splitstr').val()); //关闭iframe页面var index = ...
- jQuery 互相调用iframe页面中js的方法
1,子iframe内调用父类函数方法: window.parent.func(); 2,子Iframe中获取父界面的元素: $("#xx", window.parent.docum ...
随机推荐
- 记ByteCTF中的Node题
记ByteCTF中的Node题 我总觉得字节是跟Node过不去了,初赛和决赛都整了个Node题目,当然PHP.Java都是必不可少的,只是我觉得Node类型的比较少见,所以感觉挺新鲜的. Nothin ...
- apt和apt-get的区别
目录 一.简介 二.apt vs apt-get 为什么apt首先被引入? apt和apt-get之间的区别 apt和apt-get命令之间的区别 我应该使用apt还是apt-get? 三.结论 一. ...
- Tableau如何绘制双柱折线组合图2
一.数据源准备 二.创建计算字段月度-拖拽至列-右键-精确日期 CASE[指标] WHEN "同期"then DATETRUNC('day',[日期])-5 WHEN " ...
- [BUUCTF]REVERSE——[V&N2020 公开赛]strangeCpp
[V&N2020 公开赛]strangeCpp 附加 步骤 查壳,无壳,64位程序 64位ida载入,没有main函数,根据程序里的字符串,去查看函数 __int64 __fastcall s ...
- 合并函数Combiner.Combine…(Power Query 之 M 语言)
按相同分隔符合并: =Combiner.CombineTextByDelimiter("分隔符", 引号字符) 分隔符 直接输入 特殊符号 制表符:#(tab) 回车:#(cr) ...
- vscode提示提示安装似乎损坏,请重新安装
安装 Fix VSCode Checksums 插件 Ctrl+Shift+P , 输入Fix Checksums : Apply, 点击,重启即可
- CF699A Launch of Collider 题解
Content 有 \(n\) 辆车在一条数轴上,第 \(i\) 辆车在 \(a_i\) 上,每辆车要么向左,要么向右.开始,它们以 \(1\) 个单位每秒的速度在行驶.问你第一次撞车发生在第几秒的时 ...
- Python3 json &pickle 数据序列化
json 所有语言通用的信息交换格式 json.dumps()将list列表.dict字典.元组.函数等对象转换为可以存储的字符格式存入文件 json.dump(数据对象名,已以写方式打开的对象) 直 ...
- MySQLs数据库建外键时自动跑到缩影处,真奇怪
MySQLs数据库建外键时自动跑到缩影处,真奇怪MyISAM引擎不支持外键:InnoDB存储引擎支持外键.如何解决的,把表修改成innodb类型吧用的工具是SQLyog Ultimate如图所示:
- JAVA验证身份证号码是否正确
package com.IdCard; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.D ...