无法使用具有正确凭据的Spring 3.1对LDAP帐户进行身份验证

时间:2013-09-02 11:51:12

标签: java security spring-ldap

我正在尝试使用LDAP配置spring security。它可以与默认的用户服务一起使用,但是当我在安全上下文中配置LDAP时,我无法对用户进行身份验证。以下是我的安全配置:

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                    http://www.springframework.org/schema/security 
                    http://www.springframework.org/schema/security/spring-security-3.1.xsd">


       <beans:bean id="ldapContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <beans:constructor-arg value="ldap://authserver:389/dc=mydomain,dc=net"/>
    </beans:bean>
      <beans:bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
        <beans:constructor-arg>
            <beans:bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
                <beans:constructor-arg ref="ldapContextSource"/>
                <beans:property name="userDnPatterns">
                    <beans:list>
                        <beans:value>uid={0},ou=people</beans:value>
                    </beans:list>
                </beans:property>
            </beans:bean>
        </beans:constructor-arg>
        <beans:constructor-arg>
            <beans:bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
                <beans:constructor-arg ref="ldapContextSource"/>
                <beans:constructor-arg value="ou=Groups"/>
                <beans:property name="groupRoleAttribute" value="cn"/>
            </beans:bean>
        </beans:constructor-arg>
    </beans:bean>

 <authentication-manager>
   <authentication-provider ref="ldapAuthProvider" />
</authentication-manager>
<http use-expressions="true">
    <intercept-url pattern="/index" access="permitAll" />
    <intercept-url pattern="/login" access="permitAll"/>
    <intercept-url pattern="/loginfailed" access="permitAll" />
    <intercept-url pattern ="/failure" access="permitAll"/>
    <intercept-url pattern="/home" access="permitAll"/>
    <intercept-url pattern="/resources/**" access="permitAll" />
    <intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')" />
    <intercept-url pattern="/secure/**" access="isAuthenticated()" />
    <!--  intercept-url pattern="/**" access="denyAll" / -->
    <form-login login-page="/login" default-target-url="/secure" 
             authentication-failure-url="/loginfailed" />
           <logout logout-success-url="/index" />  

</http>
</beans:beans>

当我使用登录表单提供用户名和密码时,我在日志中看到以下行:

07:37:47 [http-bio-8181-exec-57] FilterChainProxy - /j_spring_security_check at position 1 of 9 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
07:37:47 [http-bio-8181-exec-57] HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
07:37:47 [http-bio-8181-exec-57] HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@d3b8dae. A new one will be created.
07:37:47 [http-bio-8181-exec-57] FilterChainProxy - /j_spring_security_check at position 2 of 9 in additional filter chain; firing Filter: 'LogoutFilter'
07:37:47 [http-bio-8181-exec-57] FilterChainProxy - /j_spring_security_check at position 3 of 9 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
07:37:47 [http-bio-8181-exec-57] UsernamePasswordAuthenticationFilter - Request is to process authentication
07:37:47 [http-bio-8181-exec-57] ProviderManager - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
07:37:47 [http-bio-8181-exec-57] LdapAuthenticationProvider - Processing authentication request for user: testuser
07:37:47 [http-bio-8181-exec-57] BindAuthenticator - Attempting to bind as uid=testuser,ou=people,dc=mydomain
07:37:47 [http-bio-8181-exec-57] DefaultSpringSecurityContextSource - Removing pooling flag for user uid=testuser,ou=people,dc=mydomain
07:37:48 [http-bio-8181-exec-57] BindAuthenticator - Failed to bind as uid=testuser,ou=people: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]
07:37:48 [http-bio-8181-exec-57] UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
07:37:48 [http-bio-8181-exec-57] UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
07:37:48 [http-bio-8181-exec-57] UsernamePasswordAuthenticationFilter - Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@23ec84dc
07:37:48 [http-bio-8181-exec-57] SimpleUrlAuthenticationFailureHandler - Redirecting to /loginfailed
07:37:48 [http-bio-8181-exec-57] DefaultRedirectStrategy - Redirecting to '/skweb/loginfailed'

我在使用earch和其他网站后尝试了各种组合,但显然我遗漏了一些非常基本的东西。

****更新 我尝试使用一个简单的java程序,使用UnboundID sdk尝试对同一个ldap服务器进行身份验证,并在第一次尝试时连接。

这只是表明我的Spring配置中存在不正确的内容,但我无法找到它。我尝试过使用BindAuthenticator以及密码比较方法。 Spring安全性中是否有一些配置可能导致密码以与我们的ldap服务器不同的方案加密?

    static boolean authenticate(String username, String password) throws LDAPException {
    LDAPConnection ldap = new LDAPConnection("authserver", 389);
    SearchResult sr = ldap.search("ou=people,dc=mydomain,dc=net", SearchScope.SUB, "(uid=" + username + ")");
    if (sr.getEntryCount() == 0)
        return false;

    String dn = sr.getSearchEntries().get(0).getDN();

    try {
        ldap = new LDAPConnection("authserver", 389, dn, password);
        return true;
    }
    catch (LDAPException e) {
        if (e.getResultCode() == ResultCode.INVALID_CREDENTIALS)
            return false;

        throw e;
    }
}

1 个答案:

答案 0 :(得分:0)

OP解决方案。

我可以在更改安全上下文后解决此问题,如下所示:

  <authentication-manager>   
    <ldap-authentication-provider user-search-filter="(uid={0})"
      user-search-base="ou=people"
      group-role-attribute="cn" 
      group-search-base="ou=group"
      group-search-filter="(memberUid={1})"/> 
 </authentication-manager> 

用户搜索过滤器是缺失的部分。上一个条目(uid = {0},ou = people)导致在ldap中查找不正确,因为它在格式中使用了uid而不是cn。搜索过滤器显式使用uid在ou = people中搜索id。