spring security—sp超时时slo失败

pgccezyw  于 2021-10-10  发布在  Java
关注(0)|答案(1)|浏览(475)

使用spring security saml 1.0.10,当sp上的saml会话超时,但idp上仍处于活动状态时,slo尝试失败。
如何繁殖
将会话超时设置为一分钟(server.servlet.session=1m)
登录您的sp
登录到其他辅助sp-它必须使用sso
请等待一分钟,等待会话超时
在辅助sp上进行锁定
这会在spring中导致classcastexception,因为 SecurityContextHolder.getContext().getAuthentication() 包含 AnonymousAuthenticationToken 其中不包含凭据。它还会断开过滤链,并且永远不会向idp发送logoutresponse,并且浏览器中会显示错误页面。

java.lang.ClassCastException: class java.lang.String cannot be cast to class org.springframework.security.saml.SAMLCredential (java.lang.String is in module java.base of loader 'bootstrap'; org.springframework.security.saml.SAMLCredential is in unnamed module of loader 'app')
at org.springframework.security.saml.SAMLLogoutProcessingFilter.processLogout(SAMLLogoutProcessingFilter.java:172)

这是故意的,是一个bug,还是我对某些东西的配置有误?如果是故意的,或者是一个bug,是否存在解决方法?

zdwk9cvp

zdwk9cvp1#

错误发生在 SAMLLogoutProcessingFilter.processLogout() 其中,以下代码导致classcastexception。如果用户会话已超时 auth.getCredentials() 返回一个空字符串。

SAMLCredential credential = null;
if (auth != null) {
    credential = (SAMLCredential)auth.getCredentials();
}

我发现的唯一解决方法是创建一个logoutfilter来处理这个问题。
我创建了一个新的logoutfilter,扩展了samllogoutprocessingfilter。对于logoutrequest和匿名AuthenticationToken,我创建了logoutresponse。在任何其他情况下,我转发到samllogoutprocessingfilter,或者调用samllogoutprocessingfilter中方法的副本,在这里我删除了失败的部分。

private void overwrittenLogout(HttpServletRequest request, HttpServletResponse response, SAMLMessageContext context)
      throws ServletException, SAMLException, MetadataProviderException, MessageEncodingException
  {  
      var auth = SecurityContextHolder.getContext().getAuthentication();
      if (auth instanceof AnonymousAuthenticationToken) {
          logoutProfile.sendLogoutResponse(context, StatusCode.SUCCESS_URI, null);
      } else if (auth != null) {
          followNormalProcedure(request, response, auth, context);
      }
  }

相关问题