Spring security SP超时时SLO失败
使用Spring Security SAML 1.0.10,当SP上的SAML会话超时,但IdP上仍处于活动状态时,SLO尝试失败 如何繁殖Spring security SP超时时SLO失败,spring-security,spring-saml,Spring Security,Spring Saml,使用Spring Security SAML 1.0.10,当SP上的SAML会话超时,但IdP上仍处于活动状态时,SLO尝试失败 如何繁殖 将会话超时设置为一分钟(server.servlet.session=1m) 登录您的SP 登录到其他辅助SP-它必须使用SSO 请等待一分钟,等待会话超时 在辅助SP上进行锁定 这会在Spring中导致ClassCastException,因为SecurityContextHolder.getContext().getAuthentication()包含
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,还是我对某些东西的配置有误?
如果是故意的或是错误,是否存在解决方法?错误发生在
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);
}
}