我有一个独特的场景我试图在Spring Security插件的限制下解决(版本1.2.7.3,如果是好的)。我创建了一个自定义SSO插件,允许使用签名URL登录。自定义插件工作得很好,我根据文档添加了在resources.groovy中创建bean并添加到BootStrap.groovy中的过滤器链中。
SpringSecurityUtils.clientRegisterFilter('ssoFilter', SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order + 10)
一旦用户登录,一切运行良好,并且添加到安全上下文的现有活动会话将对用户进行身份验证。
我有一个用例,在这个用例中,已经过身份验证的用户可能会在SSO请求中与不同的用户返回同一浏览器(即同一会话cookie)。我想让过滤器链注意到URL的查询字符串中的'sso = true'。
我现在看到的行为是从未到达SSO,因为原始用户已经被安全上下文验证。我无法在SecurityContextPersistenceFilter之前添加SSO过滤器,因为这会导致SSO过滤器不断被命中并且实际上没有实际呈现的问题。这是在文档之后,我看到它说你不应该在安全上下文过滤器之前放置任何过滤器。
我已经考虑过专门为具有'sso = true'的网址创建一个特殊的过滤器链(我在未经身份验证的流程中通过向{{{{{}}添加自定义RequestMatcher和AuthenticationEntryPoint实现来执行此操作3}})使用springsecurity.filterChain.chainMap配置说。但是,从文档和实验中可以看出,只过滤了路径。
有没有办法确保在URL上看到'sso = true'时,SSO过滤器在仍具有安全上下文可用性的情况下被命中,或者SecurityContextPersistenceFilter可以将请求传递给SSO过滤器?
答案 0 :(得分:5)
在我看来,您可以使用自定义SecurityContextRepository
。
Version 1.2.7.3似乎使用了Spring Security 3.0.7。正如Section 8.3.1 of the Spring Security reference中提到的,从Spring Security 3.0开始,SecurityContextPersistenceFilter
配置了SecurityContextRepository
bean,负责加载和保存SecurityContext
。默认情况下,这是HttpSessionSecurityContextRepository
的实例。
您可以创建一个扩展HttpSessionSecurityContextRepository
的自定义类。如果请求包含sso=true
查询参数,则自定义子类可以覆盖loadContext(HttpRequestResponseHolder)方法以删除“SPRING_SECURITY_CONTEXT”会话属性。
您可以在GitHub上查看Spring Security 3.0.7中HttpSessionSecurityContextRepository
的实现:
https://github.com/spring-projects/spring-security/blob/3.0.7.RELEASE/web/src/main/java/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java
答案 1 :(得分:1)
丹尼尔, 您的解决方案有效 这是我的片段
@Override
public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {
logger.debug("loadContext entry");
String ssoParameter = requestResponseHolder.getRequest().getParameter("sso");
if (ssoParameter != null && ssoParameter.equalsIgnoreCase("true")) {
HttpSession session = requestResponseHolder.getRequest().getSession(false);
if (session != null) session.invalidate();
}
return super.loadContext(requestResponseHolder);
}