Tomcat 和 spring-security 中的 Web 应用程序和 REST 服务 SSO

Posted

技术标签:

【中文标题】Tomcat 和 spring-security 中的 Web 应用程序和 REST 服务 SSO【英文标题】:Web Application and REST services SSO in tomcat and spring-security 【发布时间】:2012-06-09 03:14:30 【问题描述】:

我正在使用部署在同一个 tomcat 实例中的两个不同的 Web 应用程序。一种是 Web 应用程序,另一种是 REST 服务。当用户登录到 Web 应用程序并调用 REST 服务时,REST 应该对使用 Web 应用程序登录的用户进行身份验证。我如何在tomcat中实现SSO>如果有人实现了它,请帮助mw。

更新: 我在我的第一个 Web 应用程序中实现了 Spring Security 和 J2EEPreAuthentication 机制。此应用程序使用 DOJO(javascript 框架)调用第二个应用程序(REST 服务)。

更新: 我找到了解决方案。请在下面阅读我的回答。

【问题讨论】:

【参考方案1】:

我们可以在传统的 Web 应用程序和非基于 Web 的应用程序(如 RESTful Web 服务)之间实现 SSO。此示例显示了用于在 Web 应用程序和 RESTful Web 服务之间实现 SSO 的示例代码。以下是spring-security.xml文件中的配置

<security:http create-session="never" use-expressions="true" 
                   auto-config="false" 
                   entry-point-ref="preAuthenticatedProcessingFilterEntryPoint" >

        <security:intercept-url pattern="/**" access="permitAll"/>
        <security:intercept-url pattern="/admin/**" access="hasRole('tomcat')"/>
        <security:intercept-url pattern="/**" access="hasRole('tomcat')"/>
        <security:custom-filter position="PRE_AUTH_FILTER" ref="preAuthFilter"/>
        <!-- Required for Tomcat, will prompt for username / password twice otherwise -->
        <security:session-management session-fixation-protection="none"/>
    </security:http>

    <bean id="preAuthenticatedProcessingFilterEntryPoint"
                class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>

    <bean id="preAuthFilter"
                class="org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter">
        <property name="authenticationManager" ref="appControlAuthenticationManager"/>
        <property name="authenticationDetailsSource"
                        ref="j2eeBasedPreAuthenticatedWebAuthenticationDetailsSource"/>
    </bean> 

    <security:authentication-manager alias="appControlAuthenticationManager">
        <security:authentication-provider ref="preAuthenticatedAuthenticationProvider"/>
    </security:authentication-manager>

    <bean id="preAuthenticatedAuthenticationProvider"
                class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <property name="preAuthenticatedUserDetailsService" ref="inMemoryAuthenticationUserDetailsService"/>
    </bean>

    <bean id="j2eeBasedPreAuthenticatedWebAuthenticationDetailsSource"
                class="org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource">
        <property name="mappableRolesRetriever" ref="webXmlMappableAttributesRetriever"/>
        <property name="userRoles2GrantedAuthoritiesMapper" ref="simpleAttributes2GrantedAuthoritiesMapper"/>
    </bean>

    <bean id="webXmlMappableAttributesRetriever"
                class="org.springframework.security.web.authentication.preauth.j2ee.WebXmlMappableAttributesRetriever"/>

    <bean id="simpleAttributes2GrantedAuthoritiesMapper"
                class="org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper">
        <property name="attributePrefix" value=""/>
    </bean>

    <bean id="inMemoryAuthenticationUserDetailsService"
                class="com.org.InMemoryAuthenticationUserDetailsService"/> 

以上代码在 Web 应用程序中。同样的代码也可以在 REST 项目的 spring security xml 文件中。将以下代码添加到web.xml 文件中:

<security-constraint>
        <web-resource-collection>
            <web-resource-name>Wildcard means whole app requires authentication</web-resource-name>
            <url-pattern>/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>tomcat</role-name>
        </auth-constraint>

        <user-data-constraint>
            <!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE -->
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
    <login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
            <form-login-page>/login.jsp</form-login-page>
            <form-error-page>/error.jsp</form-error-page>
        </form-login-config>
    </login-config>

上面的代码应该只在普通的网络应用程序中。然后在 tomcat 的server.xml 文件中启用 SSO 阀。 Tomcat 使用基于 cookie 的 SSO 登录。会话 ID 存储在 cookie 中。如果您的浏览器禁用了 cookie,那么 SSO 将不起作用。

希望这个解释有所帮助。

【讨论】:

【参考方案2】:

Tomcat 提供开箱即用的 SSO 功能(通过配置),但它使用自己的身份验证机制。我不相信您可以将 Tomcat 的容器管理的 SSO 与应用程序管理的(在本例中为 Spring)身份验证机制混合使用。

如果存在 Spring 的 SSO 功能,您应该查看它们。

【讨论】:

我们可以使用J2EEPreAutenticationProvider将tomcat认证与spring混合。我可以那样做。但是,我需要 REST 服务和另一个普通 Web 应用程序的 SSO 实现

以上是关于Tomcat 和 spring-security 中的 Web 应用程序和 REST 服务 SSO的主要内容,如果未能解决你的问题,请参考以下文章

在tomcat中显示Spring-security的SQL错误

Tomcat8+Spring-Security 启用安全通道(https)的一步步实现

Spring-security:即使在 JVM 重启后也能保持活动会话

有啥方法可以强制在 spring-security 中的某些页面使用 https 吗?

使用 Tomcat 和 NodeJS 进行单点登录

在tomcat上的grails spring security中登录用户的会话