簡體   English   中英

Spring 3.1 LDAP身份驗證過程:憑據“良好”時出現“錯誤憑據”消息

[英]Spring 3.1 LDAP Authentication Process: “Bad Credentials” msg When Credentials Are Good

Spring 3.1 Tomcat 6. *

我正在制作一個Spring 3.1 webapp,用LDAP進行身份驗證。

我使用我編寫的JNDI樣式的Java程序測試了LDAP憑據(用戶名,密碼,ldap URL,搜索模式)(引用如下)。 該程序工作,轉儲所有用戶屬性,包括密碼,似乎在LDAP服務器上加密。

當我嘗試在Spring 3.1中使用相同的憑據登錄時,我收到錯誤消息“Bad Credentials”。

我在日志中收到此消息:

DEBUG [org.springframework.security.authentication.ProviderManager:authenticate] (ProviderManager.java:152) - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
DEBUG [org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider:authenticate] (AbstractLdapAuthenticationProvider.java:51) - Processing authentication request for user: John.A.Smith
DEBUG [org.springframework.security.ldap.authentication.BindAuthenticator:bindWithDn] (BindAuthenticator.java:108) - Attempting to bind as uid=John.A.Smith,ou=People,o=acme.com,o=acme.com
DEBUG [org.springframework.security.ldap.DefaultSpringSecurityContextSource$1:setupEnvironment] (DefaultSpringSecurityContextSource.java:76) - Removing pooling flag for user uid=John.A.Smith,ou=People,o=acme.com,o=acme.com
DEBUG [org.springframework.security.ldap.authentication.BindAuthenticator:handleBindException] (BindAuthenticator.java:152) - Failed to bind as uid=John.A.Smith,ou=People,o=acme.gov: org.springframework.ldap.AuthenticationException: [LDAP: error code 32 - No Such Object]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 32 - No Such Object]
DEBUG [org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter:unsuccessfulAuthentication] (AbstractAuthenticationProcessingFilter.java:340) - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials

在我的* -security.xml中,我嘗試使用標簽進行密碼比較和編碼,但它沒有幫助。 我嘗試使用md4,md5,plaintext,sha,sha-256,{ssha},{sha}無濟於事。

   <s:authentication-manager>
        <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People,o=noaa.gov" >
          <s:password-compare hash="md5">
            <s:password-encoder hash="md5"/>
          </s:password-compare>
        </s:ldap-authentication-provider>
      </s:authentication-manager>

我的網絡組織是一個龐大,緩慢,官僚組織。 我有沒有辦法告訴他們使用什么編碼,如果有的話,不聯系他們?

我可以查看的任何想法嗎?

這是我上次嘗試的* -security.xml以及我能夠連接的Java LDAP演示

謝謝。

我的* -security.xml文件:

<beans xmlns="http://www.springframework.org/schema/beans"  
  xmlns:s="http://www.springframework.org/schema/security"  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  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">  



  <s:http auto-config="true" use-expressions="true">  
    **<s:intercept-url pattern="/welcome*" access="isAuthenticated()" />** 
    <s:form-login login-page="/login" default-target-url="/welcome"  
      authentication-failure-url="/loginfailed" />  
    <s:logout logout-success-url="/logout" />  
  </s:http>  



  <s:ldap-server url = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"/>  

  <s:authentication-manager>
    <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People,o=noaa.gov" />
  </s:authentication-manager>

</beans>  

以下是使用相同憑據的JNDI樣式LDAP Java程序:

import javax.naming.*;  
import javax.naming.directory.*;  
import java.util.*;  
import java.sql.*;  

public class LDAPDEMO {  

    public static void main(String args[]) {  

        String lcf                = "com.sun.jndi.ldap.LdapCtxFactory";  
        String ldapurl            = "ldap://ldap-itc.sam.acme.com:636/o=acme.com";  
        String loginid            = "John.A.Smith";  
        String password           = "passowordforjohn";  
        DirContext ctx            = null;  
        Hashtable env             = new Hashtable();  
        Attributes attr           = null;  
        Attributes resultsAttrs   = null;  
        SearchResult result       = null;  
        NamingEnumeration results = null;  
        int iResults              = 0;  


        env.put(Context.INITIAL_CONTEXT_FACTORY, lcf);  
        env.put(Context.PROVIDER_URL, ldapurl);  
        env.put(Context.SECURITY_PROTOCOL, "ssl");  
        env.put(Context.SECURITY_AUTHENTICATION, "simple");  
        env.put(Context.SECURITY_PRINCIPAL, "uid=" + loginid + ",ou=People,o=acme.com");  
        env.put(Context.SECURITY_CREDENTIALS, password);  
        try {  

            ctx     = new InitialDirContext(env);  
            attr    = new BasicAttributes(true);  
            attr.put(new BasicAttribute("uid",loginid));  
            results = ctx.search("ou=People",attr);  

            while (results.hasMore()) {  
                result       = (SearchResult)results.next();  
                resultsAttrs = result.getAttributes();  

                for (NamingEnumeration enumAttributes  = resultsAttrs.getAll(); enumAttributes.hasMore();) {  
                    Attribute a = (Attribute)enumAttributes.next();  
                    System.out.println("attribute: " + a.getID() + " : " + a.get().toString());  


                }// end for loop  

                iResults++;  
            }// end while loop  

            System.out.println("iResults == " + iResults);  

        }// end try  
        catch (Exception e) {  
            e.printStackTrace();  
        }  



    }// end function main()  
}// end class LDAPDEMO  


Luke Taylor的評論幫助我完成了配置工作:

您的配置錯誤,因為您在LDAP服務器URL中有“o = acme.com”,並且在用戶DN模式中也使用“o = acme.com”。

我從DN模式中取出了“o = acme.com”並且LDAP工作了。 我最初將“o = acme.com”放在LDAP URL和DN模式中,因為我是Spring 3.1和LDAP的新手,這類似於它在LDAP的JNDI版本中的實現方式。我根據我要替換的遺留代碼編寫的演示。

這是我的* -security.xml的最終工作版本

<beans xmlns="http://www.springframework.org/schema/beans"  
  xmlns:s="http://www.springframework.org/schema/security"  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  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">  



  <s:http auto-config="true" use-expressions="true">  
    **<s:intercept-url pattern="/welcome*" access="isAuthenticated()" />** 
    <s:form-login login-page="/login" default-target-url="/welcome"  
      authentication-failure-url="/loginfailed" />  
    <s:logout logout-success-url="/logout" />  
  </s:http>  



  <s:ldap-server url = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"/>  

  <s:authentication-manager>
    <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People" />
  </s:authentication-manager>

</beans>  

我將探討他的其他評論,看看我是否可以重新輸入密碼或者是否需要。

您的Java示例使用標准綁定身份驗證,但您已將Spring Security配置設置為對用戶密碼執行LDAP比較操作 這將失敗,因為LDAP服務器未使用與Spring Security的MD5編碼器相同的密碼編碼格式。 要使比較操作成功,存儲的值必須與發送到目錄的字符串匹配。 在大多數情況下,您希望使用標准LDAP(綁定)身份驗證。 您可能需要為身份驗證提供程序使用bean配置。 嘗試使用:

<s:ldap-server id="contextSource" url="ldap://ldap-itc.sam.acme.com:636/o=acme.com"/>

<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
 <constructor-arg>
   <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
     <constructor-arg ref="contextSource"/>
     <property name="userDnPatterns">
       <list><value>uid={0},ou=People</value></list>
     </property>
   </bean>
 </constructor-arg>
 <constructor-arg>
   <bean class="org.springframework.security.ldap.authentication.NullLdapAuthoritiesPopulator"/>
 </constructor-arg>
  <property name="authoritiesMapper">
    <bean class="class="org.springframework.security.core.authority.mapping">
       <property name="defaultAuthority" value="ROLE_USER" />
    </bean>
  </property>   
</bean>

<s:authentication-manager>
  <s:authentication-manager ref="ldapAuthProvider" />
</s:authentication-manager>

我建議您也閱讀參考手冊的LDAP章節

此外,如果您想知道身份驗證失敗的原因,最好找出LDAP服務器本身的日志。 如果您沒有完全訪問權限,請查看其設置方式並使用您可以完全控制的本地服務器(例如OpenLDAP)。

我會試試運氣。 幾周前我遇到了類似的問題。 沒有錯誤,正確的用戶/通行證和錯誤的憑據錯誤。

首先,我建議您激活Spring安全性的調試級別。 您將獲得更多信息。 在我的情況下,這幫助我看到問題是我的用戶沒有任何角色關聯,而Spring將其描述為“錯誤的憑據”錯誤。 這可能是你的情況。 核實。

無論如何,錯誤的憑證並不意味着總是用戶/傳遞不正確。

編輯:使用log4j激活調試級別:

<logger name="org.springframework.security">
    <level value="DEBUG" />
</logger>

在您的配置中,可以讀取訪問歡迎頁面需要管理員角色:ROLE_ADMIN。 如果你不想要角色,你應該嘗試這樣的事情:

<s:intercept-url pattern="/welcome*" access="isAuthenticated()" />  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM