如何使用 spring-security-saml 让全局注销在多租户 SAML 应用程序中工作?

How can I get Global Logout working in a multi tenant SAML application using spring-security-saml?

我正在处理的多租户 SAML 应用程序使用 spring-security-saml 并包含两个服务提供商和一个 IDP(活动目录联合服务)。将 SSO 应用到此应用程序中的开发人员选择使其成为多租户,因为它是具有两个不同接口的双重用途应用程序 - 本质上是两个应用程序合二为一。它被设计为在打开两个选项卡的浏览器中使用,因此一个界面在第一个选项卡中运行,另一个界面在第二个选项卡中运行。除了一个特定的工作流程外,一切似乎都在正常工作:

  1. 打开浏览器,导航到 ADFS 登录页面,然后使用第一个服务提供商登录应用程序
  2. 打开另一个选项卡,导航到 ADFS 登录页面,然后选择第二个服务提供商
  3. 执行全局注销

日志文件包含如下错误:

Message a598hd6ff68479a44c3495f7h4216aa not found in session 11cfm6ja982te14dxxul71iufg Received logout response is invalid InResponseToField in LogoutResponse doesn't correspond to sent message a598hd6ff68479a44c3495f7h4216aa

我怀疑这与选项卡之间共享相同的 JSESSIONID cookie 这一事实有关,因此当一个 SP 注销时,它会终止关联的会话。然后,当另一个 SP 尝试使用同一个会话注销时,它会失败,因为会话已经消失。有人可以帮我解决这个问题吗?

我终于能够通过在 SecurityContextLogoutHandler bean 中将 invalidateHttpSession 设置为 false 来使其正常工作。现在,当第一个服务提供商注销时,身份验证仍然会被清除,但会话仍然存在。然后当第二个服务提供者注销时,它找到会话并注销成功。这应该没问题,因为 Jetty 默认情况下会在 30 分钟不活动后使会话超时。这是我更改的 bean:

// Logout handler terminating local session @Bean public SecurityContextLogoutHandler logoutHandler() { SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler(); logoutHandler.setInvalidateHttpSession(false); logoutHandler.setClearAuthentication(true); return logoutHandler; }