2015-05-10 28 views
6

我有一个独特的场景,我试图在Spring Security插件(版本1.2.7.3,如果是currious)的约束下解决。我已经创建了一个自定义的SSO插件,允许用签名的URL登录。自定义插件效果很好,我根据文档添加了resources.groovy中的beans并添加到BootStrap.groovy中的过滤器链中。如何有条件地跳过Grails Spring Security插件筛选器链中的SecurityContextPersistenceFilter过滤器

SpringSecurityUtils.clientRegisterFilter('ssoFilter', SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order + 10) 

一旦一切都签订了用户的伟大工程,已添加到安全上下文的现有活动会话验证用户。

我有一个使用案例,可能已经通过身份验证的用户可能会在SSO请求上与不同用户在同一浏览器(即同一会话cookie)上回来。我希望过滤器链在URL的查询字符串中注意'sso = true'。

我现在看到的行为是SSO从未到达,因为原始用户已经通过安全上下文进行身份验证。我无法在SecurityContextPersistenceFilter之前添加SSO过滤器,因为这会导致SSO过滤器不断被击中而实际上没有任何呈现的问题。这跟随文档,我看到它说你不应该把任何过滤器放在安全上下文过滤器之前。

我看着特别为使用URL创建一个特殊的过滤器链“SSO =真”(什么我通过添加自定义RequestMatcherAuthenticationEntryPoint落实到DelegatingAuthenticationEntryPoint未经验证的流程中做)使用springsecurity.filterChain。 chainMap配置说。但是,从文档和实验看来,只有路径被过滤。

有没有一种方法可以确保只要在URL上看到'sso = true',在仍然具有安全上下文可用性的情况下击中了SSO筛选器,或者SecurityContextPersistenceFilter可以将请求传递给SSO筛选器?

回答

5

在我看来,你可以使用自定义SecurityContextRepository。 Spring Security的Grails插件似乎使用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”会话属性。

可以在Spring Security的3.0.7查看HttpSessionSecurityContextRepository实施GitHub上:
https://github.com/spring-projects/spring-security/blob/3.0.7.RELEASE/web/src/main/java/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java

相关:How can I use Spring Security without sessions?

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); 
}