Spring SAML单点登出失败:JSESSIONID Cookie被浏览器拦截问题
Spring Security SAML2 单点登出(SLO)会话匹配问题咨询
我们的应用基于spring-security 4.2.1和spring-security-saml2-core 1.10.0实现SAML单点登录,但单点登出(SLO)功能异常:在其他应用执行登出操作时,发送至本应用的SLO请求无法终止本地会话。
问题根源
经排查,该问题源于身份提供商(IdP)存储并在SAML登出请求中携带的JSESSIONID Cookie被浏览器拦截,导致Spring无法找到对应会话的安全上下文,进而返回错误信息No user is logged in。
问题触发流程
- 处理登出请求前,
SecurityContextPersistenceFilter因会话ID缺失创建新上下文:
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response); SecurityContext contextBeforeChainExecution = repo.loadContext(holder); try { SecurityContextHolder.setContext(contextBeforeChainExecution); chain.doFilter(holder.getRequest(), holder.getResponse()); }
- 随后,
SAMLLogoutProcessingFilter.processLogout()尝试获取安全上下文的认证对象,但该对象为null:
Authentication auth = SecurityContextHolder.getContext().getAuthentication(); SAMLCredential credential = null; if (auth != null) { credential = (SAMLCredential) auth.getCredentials(); }
- 由于
credential为null,SingleLogoutProfileImpl.processLogoutRequest()抛出异常:
// Check whether any user is logged in if (credential == null) { throw new SAMLStatusException(StatusCode.UNKNOWN_PRINCIPAL_URI, "No user is logged in"); }
已尝试的修复方案
- 设置Cookie的
SameSite属性为None,但仅在浏览器允许第三方Cookie时生效; - 使用
PartitionedCookie属性,但浏览器仍会拦截该Cookie(因Cookie被分区至IdP域名而非应用域名),且目前并非所有浏览器均支持该属性。
咨询问题
是否可通过配置或改造Spring,基于SAML登出请求中的消息内容找到正确会话?当前我们的应用使用HttpSessionSecurityContextRepository实现安全上下文查找。
内容的提问来源于stack exchange,提问作者TheFlyingPolak
相关产品推荐
相关产品推荐

