如何解决SP 超时时 SLO 失败
使用 Spring Security SAML 1.0.10,当 SAML 会话在 SP 上超时,但在 IdP 上仍处于活动状态时,SLO 尝试失败。
如何复制
这会在 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)
这是故意的,是一个错误,还是我配置错误? 如果是有意为之或存在错误,是否有解决方法?
解决方法
错误发生在 SAMLLogoutProcessingFilter.processLogout()
中,其中以下代码导致 ClassCastException。在用户会话超时的情况下,auth.getCredentials()
返回一个空字符串。
SAMLCredential credential = null;
if (auth != null) {
credential = (SAMLCredential)auth.getCredentials();
}
我发现的唯一解决方法是创建一个 LogoutFilter 来处理该问题。
我创建了一个扩展 SAMLLogoutProcessingFilter 的新 LogoutFilter。在 LogoutRequest 和 AnonymousAuthenticationToken 的情况下,我创建了一个 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);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。