Spring Saml2 和 Spring Session - 未检索到 SavedRequest(身份验证/InResponseTo 异常后无法重定向到请求的页面)

Sim*_*ong 3 spring-security opensaml spring-saml spring-session spring-security-saml2

我正在尝试使用 Spring Boot SAML2 + Spring Session 来保护我的 Web 应用程序(将部署在 K8S 上)。没有 spring-session-data-rest 或 spring-session-hazelcast 一切都很好。它可以通过 Okta 进行身份验证,并在身份验证后重定向回所请求的页面。另外,我可以使用 opensaml3 或 opensaml4。

但是,当我尝试使用 spring-session-data-rest 或 spring-session-hazelcast (只有 1 个实例,还没有集群)时,它不会重定向回请求的页面。此外,opensaml4 也会失败,并出现异常:“响应包含 InResponseTo 属性 [],但未找到已保存的身份验证请求”。有人提到 opensaml3 即将停产,所以我想让它与 opensaml4 一起使用。

这是一个示例应用程序来演示我的案例https://github.com/simonckw/redis-saml2/tree/redis。我错过了什么吗?有人有这个设置的工作样本吗?非常感谢您的帮助。

ps 我已经追踪到 HttpSessionRequestCache.java,从 SavedRequestAwareWarpper.java 调用。如果没有 spring-session-data-rest 或 spring-session-hazelcast,可以检索保存的请求,但在启用 spring-session-data-rest 或 spring-session-hazelcast 时则无法检索。在我看来,InResponseTo 异常也可能与之相关。我的 Redis 设置应该没问题。这是写入 Redis 的会话数据:

  1. “弹簧:会话:会话:过期:7c1858d1-0ea7-4a7a-8523-2abf89137771”
  2. “春天:会话:过期:1654439580000”
  3. “弹簧:会话:会话:过期:58a584d3-625e-4e0a-bef5-3aaff485ad93”
  4. “弹簧:会话:索引:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:abc@xyz.com”
  5. “春天:会话:会话:7c1858d1-0ea7-4a7a-8523-2abf89137771”
  6. “春天:会话:会话:58a584d3-625e-4e0a-bef5-3aaff485ad93”

127.0.0.1:6379> hkeys 弹簧:会话:会话:7c1858d1-0ea7-4a7a-8523-2abf89137771

  1. “sessionAttr:SPRING_SECURITY_SAVED_REQUEST”
  2. “上次访问时间”
  3. “最大非活动间隔”
  4. “创作时间”
  5. “sessionAttr:org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository.SAML2_AUTHN_REQUEST”

127.0.0.1:6379> hkeys 弹簧:会话:会话:58a584d3-625e-4e0a-bef5-3aaff485ad93

  1. “最大非活动间隔”
  2. “创作时间”
  3. “上次访问时间”
  4. “sessionAttr:SPRING_SECURITY_CONTEXT”
  5. “sessionAttr:SPRING_SECURITY_LAST_EXCEPTION”

Rob*_*nop 7

问题在于 Spring Session 正在设置SameSite=LaxSESSIONcookie。您的 servlet 容器未将其设置为打开JSESSIONID(当您不使用 Spring Session 时)。

由于 SAML 响应是从 Okta 的页面 POST 的,因此浏览器不会发送 cookie,因此 Spring 认为它不具有可在其中查找身份验证请求的会话。它使用保存的请求来协调InResponseTo属性。

SameSite您可以通过从 cookie 中删除来解决此问题。创建一个像这样的bean:

    @Bean
    public DefaultCookieSerializerCustomizer cookieSerializerCustomizer() {
        return cookieSerializer -> {
            cookieSerializer.setSameSite(null);
        };
    }
Run Code Online (Sandbox Code Playgroud)

或者,您可以显式指定None,但随后您还必须设置该Secure属性。

注意:Chrome 应该默认为未指定的Lax位置。SameSite实际上,如果HttpOnly设置了,它不会这样做。Safari 和 Firefox 似乎根本不关心HttpOnly.

这里讨论这个问题。


归档时间:

查看次数:

4297 次

最近记录:

3 年,5 月 前