Spring-WS WS-Security LDAP 身份验证

Posted

技术标签:

【中文标题】Spring-WS WS-Security LDAP 身份验证【英文标题】:Spring-WS WS-Security LDAP Authentication 【发布时间】:2015-10-20 22:02:18 【问题描述】:

我在使用 LDAP 用户身份验证与 Spring-WS 一起使用 LDAP 身份验证时遇到问题。我找到了几个如何做到这一点的例子,其中几个使用不同的 bean,有些甚至编写了自己的身份验证器。不幸的是,似乎没有人拥有所有必要的细节来完成这项工作。此外,由于似乎有几种不同的方法可以让这个工作,我不确定最好的方法。我已经尝试了 wss4j (apache) 和 xwss (sun) 安全提供程序并得到了类似的结果。我知道 ws-security 部分正在工作(它可以在没有使用 SimplePasswordValidationCallbackHandler 的 LDAP 部分的情况下正常工作),甚至 ldap 上下文也能够从 LDAP 存储库中检索用户,但最终,密码身份验证失败。另外,我不明白为什么这很重要,但我使用 Active Directory 作为我的 LDAP 提供程序...

    <sws:interceptors>
        <bean class="com.xxxxx.xxxxxx.xxxx.controller.interceptors.EcrsPayloadLoggingInterceptor"/>

        <bean class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
            <property name="policyConfiguration" value="classpath:securityPolicy.xml" />
            <property name="callbackHandlers">
                <list>
                    <ref bean="authenticationHandler"/>
                </list>
            </property>
        </bean>
    </sws:interceptors>

    <bean id="securityContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
            <constructor-arg value="ldap://localhost:389/DC=xxxx,DC=xxxx,DC=local"/>
            <property name="userDn" value="CN=user1,CN=Users,DC=xxxx,DC=xxxxx,DC=local"/>
            <property name="password" value="password1"/>
    </bean>

    <bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
            <constructor-arg name="searchBase" value=""/>
            <constructor-arg name="searchFilter" value="(sAMAccountName=0)"/>
            <constructor-arg name="contextSource" ref="apacheContextSource"/>
            <property name="searchSubtree" value="true"/>
    </bean>

    <bean id="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
            <constructor-arg name="contextSource" ref="apacheContextSource"/>
            <constructor-arg name="groupSearchBase" value="CN=Users"/>
            <property name="groupRoleAttribute" value="CN"/>
    </bean>

    <bean id="ldapUserDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
            <constructor-arg name="userSearch" ref="ldapUserSearch"/>
            <constructor-arg name="authoritiesPopulator" ref="ldapAuthoritiesPopulator"/>
    </bean>

    <bean id="authenticationHandler" class="org.springframework.ws.soap.security.xwss.callback.SpringDigestPasswordValidationCallbackHandler">
        <property name="userDetailsService" ref="ldapUserDetailsService"/>
    </bean>

securityPolicy.xml

<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true" >
    <xwss:RequireTimestamp maxClockSkew="60" timestampFreshnessLimit="300"/>
    <xwss:RequireUsernameToken passwordDigestRequired="false" nonceRequired="true"/>
</xwss:SecurityConfiguration>

【问题讨论】:

另外,这是我的 securityPolicy.xml java.sun.com/xml/ns/xwss/config" dumpMessages="true" > 【参考方案1】:

这是我找到的解决方案...

    <sws:interceptors>
        <bean class="com.xxxx.xxxxx.xxxx.controller.interceptors.EcrsPayloadLoggingInterceptor"/>

        <bean class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
            <property name="policyConfiguration" value="classpath:securityPolicy.xml" />
            <property name="callbackHandlers">
                <list>
                    <ref bean="authenticationHandler"/>
                </list>
            </property>
        </bean>
    </sws:interceptors>

    <bean id="authenticationHandler" class="org.springframework.ws.soap.security.xwss.callback.SpringPlainTextPasswordValidationCallbackHandler">
        <property name="authenticationManager" ref="authManager" />
    </bean>

    <s:authentication-manager id="authManager">
        <s:authentication-provider ref='ldapAuthProvider'/>
    </s:authentication-manager>

    <bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
       <constructor-arg>
           <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
               <constructor-arg ref="securityContextSource" />
               <property name="userSearch" ref="ldapUserSearch"/>
           </bean>
       </constructor-arg>
       <constructor-arg name="authoritiesPopulator" ref="ldapAuthoritiesPopulator"/>
    </bean>

    <bean id="securityContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
            <constructor-arg value="ldap://localhost:389/DC=xxx,DC=xxxxx,DC=local"/>
            <property name="userDn" value="CN=xxxxxx,CN=xxxx,DC=xxx,DC=xxxx,DC=local"/>
            <property name="password" value="xxxxxxx"/>
    </bean>

    <bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
            <constructor-arg name="searchBase" value=""/>
            <constructor-arg name="searchFilter" value="(sAMAccountName=0)"/>
            <constructor-arg name="contextSource" ref="securityContextSource"/>
            <property name="searchSubtree" value="true"/>
    </bean>

    <bean id="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
            <constructor-arg name="contextSource" ref="securityContextSource"/>
            <constructor-arg name="groupSearchBase" value="CN=Users"/>
            <property name="groupRoleAttribute" value="CN"/>
    </bean>

【讨论】:

以上是关于Spring-WS WS-Security LDAP 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

spring-ws:找不到端点映射

来自 WSDL 的 Spring-ws 客户端

基于Spring-WS的Restful API的集成测试

@PayloadRoot vs @Action vs @SoapAction 在 Spring-WS 中

WS-Security

Spring-ws自动生成WSDL时生成java类的最佳方式