【问题标题】:Spring Security SAML assertion expiry with Application Session ExpirySpring Security SAML 断言到期与应用程序会话到期
【发布时间】:2026-01-01 23:50:01
【问题描述】:

我对 SAML 断言到期与应用程序会话到期感到困惑。

简单来说,当我们在容器中部署了一个应用程序时,就会创建一个会话。可以使用 web.xml 中的以下条目来控制此会话到期

<session-config>
    <session-timeout>60</session-timeout>
</session-config>

继续前进,当我拥有带有 SAML 扩展的 Spring Security 时,显然同样的会话概念也适用。 (如果这很重要,我将在 WildFly 8.2 中部署应用程序)

此外,当应用会话过期时,注销行为似乎等同于本地注销的概念。

到目前为止一切顺利。现在假设 SAML 断言有效 2 小时,并且用户已经积极工作了 2 小时。那么后续的请求应该怎么办呢?是否应该重新登录 IDP?但是,这不会给用户带来不便吗?如果应用程序在断言过期 2 小时后重定向到 IDP 再次登录,应该如何处理 AJAX 请求?

这是参考the question here

【问题讨论】:

    标签: angularjs session spring-security saml-2.0 spring-saml


    【解决方案1】:

    Spring SAML 为经过身份验证的用户发出ExpiringUsernameAuthenticationToken。一旦用于对用户进行身份验证的 SAML 断言达到其 sessionNotOnOrAfter 时间,令牌就会开始在其 isAuthenticated() 方法中返回 false。

    可以通过覆盖SAMLAuthenticationProvider 并更改方法getExpirationDate(credential) 来禁用此行为,该方法返回断言到期的时间,或者null,以防它永远不会到期。然后应用程序将完全依赖容器中配置的会话过期。

    一旦ExpiringUsernameAuthenticationToken过期,Spring Security会将当前令牌传递给AuthenticationManager(在&lt;security:authentication-manager&gt;下的securityContext.xml中配置)。

    您可以通过添加自己的AuthenticationProvider 能够处理ExpiringUsernameAuthenticationToken 来影响接下来发生的事情。否则系统会因ProviderNotFoundException 或其他AuthenticationException(如BadCredentialsException)而失败(以防您同时使用用户名/密码身份验证)。

    该异常随后由ExceptionTranslationFilter 处理,它通过调用配置的身份验证EntryPoint 来启动新的身份验证过程 - 例如SAMLEntryPoint 使用默认 IDP 启动身份验证或显示 IDP 选择页面。正如您所说,该过程还将实质上执行本地注销。

    默认情况下,系统对所有 HTTP 调用的行为都是相同的 - AJAX 与否。您可以通过将 API 和普通 URL 拆分为单独的 &lt;security:http&gt; 元素并为每个元素使用不同的 EntryPoints(接口 AuthenticationEntryPoint)来定义不同的行为。例如,Http403ForbiddenEntryPoint 可能适合您的 AJAX 调用。

    【讨论】: