2012-03-28 27 views
6

Wiosna 3,1 Tomcat 6. *Wiosna 3.1 Proces uwierzytelniania LDAP: "Bad Poświadczenia" msg Gdy poświadczenia są Dobry

pracuję nad podjęciem Wiosna 3.1 webapp, uwierzytelnianie z LDAP.

Przetestowałem dane logowania LDAP (nazwa użytkownika, hasło, URL strony ldap, wzorzec wyszukiwania) za pomocą napisanego w języku JNDI programu Java, który napisałem (zacytowałem poniżej). Program działał, porzucał wszystkie atrybuty użytkowników, w tym hasło, które wydaje się być zaszyfrowane na serwerze LDAP.

Kiedy próbuję zalogować się przy użyciu tych samych poświadczeń na wiosnę 3.1, pojawia się komunikat o błędzie "Złe poświadczenia".

Mam ten post w dziennikach:

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 

Moim * -security.xml Próbowałem za pomocą tagów dokonać porównania hasło i kodowanie zdarzyć, ale to nie pomogło. Próbowałem używać md4, md5, zwykłego tekstu, sha, sha-256, {ssha}, {sha} bez skutku.

<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> 

Moja grupa networkingowa to duża, powolna biurokratyczna organizacja. Czy jest jakiś sposób, aby powiedzieć, jakiego kodowania używają, jeśli w ogóle, bez kontaktu z nimi?

Jakieś pomysły na rzeczy, które mógłbym sprawdzić?

To jest mój * -security.xml jak mojej ostatniej próby i demo Java LDAP udało mi się połączyć z

Dzięki.

My * -security.xml file:

<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> 

Oto styl JNDI Program LDAP Java, która współpracuje z tymi samymi poświadczeniami:

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 

Rozwiązanie


Komentarz od Luke Taylor pomógł mi dostać moją pracę konfiguracji:

Twoja konfiguracja jest nie tak, że masz „o = acme.com” w URL serwera LDAP i są również za pomocą " o = acme.com "we wzorze DN użytkownika.

Wyjęto "o = acme.com" ze wzoru DN i LDAP zadziałało. Pierwotnie umieściłem "o = acme.com" zarówno w adresie URL LDAP, jak i wzorzec DN, ponieważ jestem nowy w Spring 3.1 i LDAP, i to jest podobne do tego, jak to się stało/zostało zrobione w JNDI Java w LDAP wersja demo, którą napisałem na podstawie dotychczasowego kodu, który zastępuję.

Oto ostateczna, działająca wersja mojego * -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> 

Zamierzam zbadać jego drugą komentarz i zobaczyć, czy mogę umieścić z powrotem w kodowanie hasło lub jeśli muszę.

+0

Kolejna uwaga. Nie można ponownie wprowadzić kodowania hasłem, ponieważ nie wiesz, jakiego algorytmu używa serwer, a w praktyce może on używać więcej niż jednego. Hashowanie haseł dotyczy ochrony bazy danych haseł przez utrudnianie jej odczytu. Nie chodzi o to, aby uwierzytelnianie klienta było bezpieczniejsze (na ten temat można znaleźć wiele dyskusji). Jeśli chcesz uniemożliwić podsłuchiwanie w sieci z aplikacji na serwer LDAP, najpewniejszym rozwiązaniem jest użycie połączenia SSL. –

Odpowiedz

3

Twój przykład Java za pomocą standardowego uwierzytelniania wiązania, ale trzeba ustawić konfigurację zabezpieczeń Wiosna się zrobić LDAP compare operation hasło użytkownika. To się nie powiedzie, ponieważ serwer LDAP nie używa tego samego formatu kodowania haseł co koder MD5 Spring Security. Aby operacja porównania zakończyła się pomyślnie, zapisana wartość musi być zgodna z ciągiem, który jest wysyłany do katalogu. W większości przypadków chcesz użyć standardowego uwierzytelniania LDAP (bind). Prawdopodobnie będziesz potrzebować konfiguracji komponentu bean dla dostawcy uwierzytelniania. Spróbuj użyć:

<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> 

Polecam również przeczytać the LDAP chapter of the reference manual.

Ponadto, jeśli chcesz wiedzieć, dlaczego uwierzytelnienie się nie udaje, najlepszym miejscem do odkrycia jest dziennik serwera LDAP. Jeśli nie masz pełnego dostępu, dowiedz się, jak jest skonfigurowany i użyj lokalnego serwera (takiego jak OpenLDAP), w którym masz pełną kontrolę.

+0

Cześć Luke. Przeczytałem rozdział LDAP na wiosnę 3.1 kilka razy. Jest krótki i jestem nowy w LDAP i Spring. Chcę się upewnić, że rozumiem Twój komentarz. Jeśli usuniesz znaczniki , zrzucę je do standardowego powiązania, ponieważ cytowany program Java jest i NIE wykonam w ogóle porównania haseł? Czy Spring domyślnie porównuje hasła? Czy będę musiał ustawić coś, aby NIE to zrobić? – Steve

+0

Bez ich kontaktu, nie można, a porównywanie haseł nie jest świetnym pomysłem, jeśli są one kodowane (na przykład może być inaczej). Powinieneś używać uwierzytelniania powiązań, ponieważ już to udowodniłeś i zapomniałeś o porównaniu haseł. Zwykle jest używany tylko wtedy, gdy bind jest wyłączony. Czy wypróbowałeś podaną konfigurację? Jeśli tak, co się stało? –

+0

Luke, w świetle twoich komentarzy zmieniłem mój plik * server.xml i cały mój oryginalny wpis. Muszę trochę przestudiować twoją konfigurację. Jeśli to możliwe, chciałbym znaleźć sposób, aby napisać to w stylu Spring 3.1. Dam mu szansę i dam ci znać, jak to działa. Dzięki za tonę. – Steve

0

Spróbuję szczęścia. Kilka tygodni temu miałem podobny problem. Brak błędów, błąd User/Pass i Bad Credentials.

Po pierwsze, zalecam, aby aktywować poziom debugowania dla bezpieczeństwa wiosennego. Otrzymasz więcej informacji. W moim przypadku pomogło mi to zauważyć, że problem polegał na tym, że mój użytkownik nie miał przypisanej żadnej roli, a Spring ujawniał go jako błąd "złe dane uwierzytelniające". To może być twoja sprawa. Sprawdź to.

W każdym razie złe dane uwierzytelniające nie zawsze oznaczają, że użytkownik/hasło są nieprawidłowe.

EDIT: Do aktywacji poziom debugowania przy użyciu log4j:

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

w was konfiguracji, można przeczytać, że dostęp do strony wymaga witamy rolę administratora: ROLE_ADMIN. Jeśli nie chcesz role, należy spróbować czegoś takiego:

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

Jestem nowy w Spring i LDAP. Jak mogę aktywować poziom debugowania w Spring Security? Czy NIE można skojarzyć roli z użytkownikiem, a jeśli tak, to w jaki sposób? Czy mogę skojarzyć neutralną rolę z użytkownikiem? Naprawdę nie mamy ról dla użytkowników. – Steve

+0

Edytowałem odpowiedź. Jeśli nie chcesz ról, nie przypisuj ich do dostępu. – jddsantaella

+0

Próbowałem nowej wartości dostępu, którą zasugerowałeś. Bez zmiany. Gdzie mam umieścić powyższy xml logger? – Steve