简体   繁体   English

Spring Security-从SSO缓存凭据

[英]Spring Security - caching credentials from SSO

I'm updating an older program to use Spring Security. 我正在更新一个较旧的程序以使用Spring Security。 Previously, it used Acegi security, and cached the credentials after an initial check of the SSO header into a session cookie; 以前,它使用Acegi安全性,并在对SSO标头进行初步检查后将凭据缓存到会话cookie中。 with Spring Security 3.1.4, I was able to get the program checking for the SSO username header (SM_USER - and no, we don't use Siteminder anymore, but to avoid painful software updates when we switched to OAM, we configured OAM to insert the SM_USER header into requests), and working locally with a valve setup in tomcat (6.0); 使用Spring Security 3.1.4,我能够检查SSO用户名标头(SM_USER,并且不,我们不再使用Siteminder,但为了避免在切换到OAM时进行繁琐的软件更新,我们将OAM配置为将SM_USER标头插入请求中),然后在tomcat(6.0)中使用阀门设置在本地工作; however, when deployed out to the dev environment, with live SSO, it fails only on POSTS, and then, only to pages that use the same URL, but the different HTTP RequestMethod. 但是,当使用实时SSO部署到开发环境时,它仅在POSTS上失败,然后仅在使用相同URL但使用不同HTTP RequestMethod的页面上失败。 Looking at the network traffic, it seems that the difference between the old code and new is that the new code is making an OAM SSO auth request, and then the post auth redirect drops the POST data and changes the RequestMethod to GET; 从网络流量来看,旧代码和新代码之间的区别似乎是新代码正在发出OAM SSO身份验证请求,然后身份验证重定向将丢弃POST数据并将RequestMethod更改为GET; so I thought perhaps adding credential caching back into the app would fix the issue; 因此,我认为也许在应用程序中添加凭据缓存可以解决该问题; but I'm having difficulty finding a configuration that I can add in to get the caching enabled, and that's where I turn to you. 但是我很难找到可以添加以启用缓存的配置,这就是我寻求帮助的地方。

This is the security configuration that is doing per request authentication, and works locally: 这是按请求身份验证执行的安全配置,并且可以在本地运行:

    <security:http use-expressions="true" auto-config="true" entry-point-ref="http403EntryPoint">
        <security:intercept-url pattern="/**" access="isAuthenticated()" />
        <security:intercept-url pattern="/fastjump/auth/admin/*" access="hasRole('ROLE_ADMINISTRATOR')" />
        <security:intercept-url pattern="/fastjump/auth/*" access="permitAll" />
        <security:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
    </security:http>

    <bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
        <property name="principalRequestHeader" value="SM_USER"/>
        <property name="authenticationManager" ref="authenticationManager" />
    </bean>

    <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <property name="preAuthenticatedUserDetailsService">
            <bean id="userDetailsServiceWrapper"  class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                <property name="userDetailsService" ref="userDetailsService"/>
            </bean>
        </property>
    </bean>

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="preauthAuthProvider" />
    </security:authentication-manager>


    <!-- This is the class that handles actually looking up the user from the persistent store and associating their
    GrantedAuthority objects.  This custom implementation uses a PersonService object to do the lookup. -->
    <bean id="userDetailsService" class="corporate.fastjump.security.DefaultUserDetailsService">
        <property name="personService" ref="personService"/>
        <property name="fastJumpService" ref="fastJumpService"/>
    </bean>

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

I've tried adding the following to the security config: 我尝试将以下内容添加到安全配置中:

<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
    <security:filter-chain-map>
        <security:filter-chain filters="httpSessionContextIntegrationFilter, securityContextHolderAwareRequest, siteminderFilter" pattern="/fastjump/auth/**"/>
    </security:filter-chain-map>
</bean>

<bean id="httpSessionContextIntegrationFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
    <property name="securityContextRepository">
        <bean class="org.springframework.security.web.context.HttpSessionSecurityContextRepository">
            <property name="allowSessionCreation" value="false"/>
        </bean>
    </property>
</bean>

<bean id="securityContextHolderAwareRequest" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter">
</bean>

And this to the web.xml: 并将其添加到web.xml中:

<!-- This filter is used to implement request level authorization. -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<!-- Note that we only send requests which require authentication and authorization services through the
Spring Security filters -->
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/auth/*</url-pattern>
</filter-mapping>

But that now adds a basic auth challenge to the /auth context requests. 但这现在给/ auth上下文请求增加了一个基本的auth挑战。 I'm missing the piece that ties together the caching with the pre auth. 我缺少将缓存与预身份验证联系在一起的部分。 Does anyone have any suggestions? 有没有人有什么建议?

So it turns out the SSO was the problem, but not in the way we initially thought. 事实证明,SSO是问题所在,但不是我们最初的想法。 We have multiple different SSO domains (DEV, INT, PROD), and we had an autocompleter on the page in question that was hard coded to go out to a Web Service in the Prod domain, and while the Web Service API is specifically excluded in the Production domain from SSO protection (it's open to all users), the act of querying the Production server caused a query to the Production SSO domain, and overwrote the session with Production credentials. 我们有多个不同的SSO域(DEV,INT,PROD),并且该页面上有一个自动完成程序,该代码已硬编码以发送到Prod域中的Web服务,而Web Service API在此专门排除在外不受SSO保护的生产域(它对所有用户开放),查询生产服务器的操作导致对生产SSO域的查询,并使用生产凭据覆盖了会话。 Getting back to the Dev server and trying to perform a POST with the Prod creds failed, and in the process of querying the Dev SSO for the proper credentials, it dropped the POST data, and changed the html request type to GET. 回到开发服务器并尝试使用Prod凭据执行POST失败,并且在向Dev SSO查询正确凭据的过程中,它删除了POST数据,并将html请求类型更改为GET。 Our solution was to update the autocompleter to have logic to determine which server it's running on (via JavaScript, look at the host), and then build the URL for the autocompleter back end based on which environment we're in. 我们的解决方案是更新自动填充程序,使其具有逻辑来确定它在哪个服务器上运行(通过JavaScript,查看主机),然后根据我们所处的环境为自动填充程序后端构建URL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM