调用全局退出无法注销应用系统的用户会话

# 问题描述

应用系统采用Oauth2、OIDC等标准协议集成IDaaS认证服务,管理员在IDaaS企业中心的应用配置中添加应用系统的退出地址后,应用开发者经常遇到以下场景,调用全局退出时无法注销应用系统的用户会话。

  • 采用IDP-initialed发起的Sign out:用户首先登录进入IDaaS用户中心,然后访问权限范围内的应用系统App1、App2,当用户在IDaaS用户中心点击统一退出后,仅注销了SSO会话信息,但是没有同步注销应用系统的用户会话。
  • 采用SP-initiated发起的Sign out:用户首先通过IDaaS认证后访问目标应用系统App1、然后继续访问App2/3/N,当用户在某应用系统中点击退出时(该应用已集成全局退出),除了成功注销SSO会话和当前应用系统的用户会话外,但是没有同步注销其它业务系统的用户会话。

# 问题原因

1.应用系统配置的退出地址是HTTP协议,而非HTTPS协议。

因IDaaS服务是Https协议请求,当通过IDaaS的统一退出页面调用应用系统Http协议的退出地址时,浏览器会认为这个请求是不安全的,浏览器禁止该请求,造成注销应用系统的用户会话失效。

2.在跨站请求下,IDaaS调用应用系统退出地址时,应用系统不能获取到当前用户在该系统的cookie。

在跨站请求下,竹云IDaaS调用应用系统的退出地址会被浏览器限制携带Cookie,应用系统无法识别登录当前业务系统的用户身份,造成注销业务系统的用户会话失败。

# 解决方案

1.应用系统必须使用HTTPS协议访问

2.跨站场景下,服务器的cookie属性SameSite设置为“None; Secure”,声明无论是否跨站都可以发送 Cookie

采用Java HttpResponse.addHeader()设置Cookie示例:
    
response.addHeader("Set-Cookie", "CookieName=CookieValue;SameSite=None;Secure");
1
2
3

注意点:

  • HTTP接口不支持 SameSite=None。如果你想加 SameSite=None 属性,那么该 Cookie 就必须同时加上 Secure 属性,表示只有在 HTTPS 协议下该 Cookie 才会被发送。
  • 新版本的Safari默认开启“阻止跨网站跟踪”,禁止跨站访问第三方Cookie。换句话说即使应用服务器设置SameSite=None; Secure,Safari浏览器也不允许携带Cookie请求,有关说明可参考:Safari禁止第三方Cookie无法获取用户登录状态

3.使用Nginx或其他网关工具进行Proxy操作,使跨站请求变为同站请求。

# 相关参考

# SameSite属性

SameSite是 HTTP 响应头 Set-Cookie的属性之一。它允许声明该 Cookie 是否仅限于第一方或者同一站点上下文。

SameSite 可以有下面三种值:

  1. Strict 仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,即当前网页 URL 与请求目标 URL 完全一致。
  2. Lax 允许部分第三方请求携带 Cookie。
  3. None 无论是否跨站都会发送 Cookie。

之前默认是 None 的,Chrome80 后默认是 Lax。

Lax的情况见下表:

请求类型 示例 正常情况 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 不发送

当sameSite为Lax时,post、iframe、ajax、image的跨站请求都不会发送cookie。

# 参考链接