如何在两个域上使用spring security进行单一登录?

时间:2012-02-03 08:31:22

标签: java spring authentication spring-security

我有网络应用程序和两个域名 - example.com和example.ru

example.com - 国际

example.ru - 适用于本地国家/地区

我的网络应用程序使用spring security作为授权用户,但如果用户在example.ru上通过example.com登录,则不会记录。

如果用户通过example.com或example.ru登录,他将如何在两个域上登录?

PS:BTW我的网络应用程序通过OpenID和OAuth使用授权

3 个答案:

答案 0 :(得分:2)

如前所述,您需要在解决方案上使用单点登录,Cloudseal提供了一个spring安全扩展,其中包含一个spring命名空间,因此您只需要执行以下操作:

<security:http entry-point-ref="cloudseal">
    <security:intercept-url pattern="/protected/user.do" access="IS_AUTHENTICATED_FULLY" />
    <security:intercept-url pattern="/protected/admin.do" access="ROLE_ADMIN" />
</security:http>

<cloudseal:sso endpoint="http://cloudseal.com" entry-point-id="cloudseal" app-id="quickstart">
    <cloudseal:keystore location="WEB-INF/keystore.jks" password="nalle123">
        <cloudseal:key name="apollo" password="nalle123" />
    </cloudseal:keystore>
    <cloudseal:metadata location="WEB-INF/idp.xml" />
</cloudseal:sso>

请参阅www.cloudseal.com/platform/spring-security-single-sign-on

答案 1 :(得分:1)

虽然这种类型的功能实现起来并不容易实现,但实际上可以在不修改Spring的情况下实现。

实际代码太大而无法发布,因此我将尝试概述基本原理并将编码留给您。

  1. 延长春天的SavedRequestAwareAuthenticationSuccessHandler 并实现序列化和写入的功能 Authentication对象具有全局范围的会话cookie。看到 authentication-success-handler-ref属性的文档 在Spring的<sec:http>标记中有关如何连线的更多信息 这个。 (注意:如果问题是跨越多个Web应用程序的问题 在同一个域中,您当然可以将cookie范围限制为 当前域名。。
  2. 在您的所有网络应用中,添加web.xml <filter>定义 命名为springSecurityFilterChain和类 org.springframework.web.filter.DelegatingFilterProxy和a <filter-mapping>用于URL模式为/*的过滤器您不必创建实际的bean,Spring Security会为您提供默认实现。
  3. 在您的所有网络应用中,添加web.xml <filter>定义 用class命名singleSignonAuthenticationFilterChain org.springframework.web.filter.DelegatingFilterProxy和a 对应的<filter-mapping>用于具有网址格式的过滤器 /*
  4. 现在添加一个名为的新bean singleSignonAuthenticationFilterChain,应指向a implements Filter的课程。在doFilter()方法中,检查是否 有一个名为SPRING_SECURITY_CONTEXT的会话属性。如果 有,然后我们已经登录。否则,采取 序列化Authentication令牌,反序列化并使用 SecurityContextHolder.getContext().setAuthentication(authentication) 使用Spring对用户进行身份验证。还记得 session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext())或身份验证将采用 每次放置,这是不必要的。
  5. 对(4)的一个转折是,如果你发现没有名为SPRING_SECURITY_CONTEXT的属性,那么可能是因为用户刚刚从当前的Web应用程序注销。在这种情况下,他必须全局注销,因此您希望删除包含序列化身份验证令牌的cookie。

    在一页摘要中写出来有点复杂,但我希望你能得到一般的想法。我们目前在一个由多个Web应用程序组成的复杂应用程序中实现了它,并且它运行良好。

答案 2 :(得分:0)

如果不修改弹簧安全代码,这是不可能的。我有时候做过但很难维护

Cas是java世界中最简单的方法。 http://www.jasig.org/cas