2012-03-28 6 views
6

स्प्रिंग 3.1 बिलाव 6. *स्प्रिंग 3.1 LDAP प्रमाणीकरण प्रक्रिया: "बैड साख" संदेश जब साख अच्छा

मैं एक स्प्रिंग 3.1 webapp बनाने एलडीएपी से प्रमाणीकृत करने पर काम कर रहा हूँ कर रहे हैं।

मैंने एलडीएपी क्रेडेंशियल्स (उपयोगकर्ता नाम, पासवर्ड, एलडीएपी यूआरएल, सर्च पैटर्न) का परीक्षण किया जो मैंने लिखा एक जेएनडीआई स्टाइल जावा प्रोग्राम (नीचे उद्धृत) के साथ किया। उस कार्यक्रम ने काम किया, पासवर्ड सहित सभी उपयोगकर्ता विशेषताओं को छोड़ दिया, जो एलडीएपी सर्वर पर एन्क्रिप्ट किया गया प्रतीत होता है।

जब मैं वसंत 3.1 में समान प्रमाण-पत्रों के साथ लॉगिन करने का प्रयास करता हूं तो मुझे त्रुटि संदेश "खराब प्रमाण पत्र" मिलता है।

मैं लॉग में यह संदेश मिला:

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> 

मेरा नेटवर्किंग समूह एक बड़ा, धीमा, नौकरशाही संगठन है। क्या कोई तरीका है कि मैं बता सकता हूं कि वे किस एन्कोडिंग का उपयोग करते हैं, अगर कोई है, तो उनसे संपर्क किए बिना?

चीजों के बारे में कोई भी विचार जो मैं देख सकता हूं?

यह मेरा आखिरी प्रयास और जावा LDAP डेमो मैं साथ

धन्यवाद कनेक्ट कर सकता था की के रूप में मेरे * -security.xml है।

मेरे * -security.xml फ़ाइल:

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 

समाधान:

<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 जावा प्रोग्राम है कि एक ही पहचान के साथ काम करता है


ल्यूक टेलर से यह टिप्पणी मुझे मेरे विन्यास काम करने में मदद मिली:

आपका विन्यास कि में गलत है तुम हो "ओ = acme.com" LDAP सर्वर URL में और भी प्रयोग कर रहे हैं " ओ = acme.com "उपयोगकर्ता डीएन पैटर्न में।

मैंने डीएन पैटर्न से बाहर "ओ = acme.com" लिया और एलडीएपी ने काम किया। मैंने मूल रूप से एलडीएपी यूआरएल और डीएन पैटर्न दोनों में "ओ = acme.com" रखा था क्योंकि मैं स्प्रिंग 3.1 और एलडीएपी के लिए नया हूं, और यह एलडीएपी के जावा जेएनडीआई संस्करण में कैसे किया गया है/जैसा किया गया है डेमो मैंने लीगेसी कोड के आधार पर लिखा है जिसे मैं बदल रहा हूं।

यहां मेरे * -सुरिटी का अंतिम, कामकाजी संस्करण है।एक्सएमएल

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

मैं अपने अन्य टिप्पणी का पता लगाने और देखें कि क्या मैं में या अगर मैं करने की जरूरत है वापस पासवर्ड एन्कोडिंग रख सकते हैं करने के लिए जा रहा हूँ।

+0

एक और नोट। आप पासवर्ड एन्कोडिंग को वापस नहीं डाल सकते हैं, क्योंकि आप नहीं जानते कि सर्वर किस एल्गोरिदम का उपयोग कर रहा है और व्यवहार में यह एक से अधिक का उपयोग कर सकता है। हैशिंग पासवर्ड पासवर्ड डेटाबेस को सुरक्षित करना इसे कठिन बनाकर सुरक्षित करना है। यह क्लाइंट प्रमाणीकरण को और अधिक सुरक्षित बनाने के बारे में नहीं है (आपको इस पर कई चर्चाएं मिलेंगी)। यदि आप अपने ऐप से एलडीएपी सर्वर पर नेटवर्क पर ईव्सड्रॉपिंग को रोकना चाहते हैं, तो एसएसएल कनेक्शन का उपयोग करना शायद सबसे आसान विकल्प है। –

उत्तर

3

आपका जावा उदाहरण मानक बाँध प्रमाणीकरण का उपयोग कर रहा है, लेकिन आप उपयोगकर्ता का पासवर्ड पर एक LDAP compare operation करने के लिए स्प्रिंग सुरक्षा विन्यास निर्धारित किया है। यह असफल हो जाएगा क्योंकि एलडीएपी सर्वर स्प्रिंग सिक्योरिटी के एमडी 5 एन्कोडर के समान पासवर्ड एन्कोडिंग प्रारूप का उपयोग नहीं कर रहा है। तुलना करने के लिए एक तुलना ऑपरेशन के लिए, संग्रहीत मान निर्देशिका में भेजे गए स्ट्रिंग से मेल खाना चाहिए। ज्यादातर मामलों में आप मानक एलडीएपी (बाइंड) प्रमाणीकरण का उपयोग करना चाहते हैं। आपको प्रमाणीकरण प्रदाता के लिए शायद एक बीन कॉन्फ़िगरेशन का उपयोग करने की आवश्यकता होगी। उपयोग करके देखें:

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

मैं सलाह देते हैं तो आप भी the LDAP chapter of the reference manual पढ़ें।

इसके अलावा, अगर आप जानना चाहते हैं कि प्रमाणीकरण क्यों विफल हो रहा है, तो पता लगाने के लिए सबसे अच्छी जगह एलडीएपी सर्वर के लिए लॉग है। यदि आपके पास पूर्ण पहुंच नहीं है, तो पता लगाएं कि यह कैसे स्थापित किया गया है और स्थानीय सर्वर (जैसे ओपनएलडीएपी) का उपयोग करें जहां आपके पास पूर्ण नियंत्रण है।

+0

हाय ल्यूक। मैंने कई बार वसंत 3.1 में एलडीएपी अध्याय पढ़ा। यह संक्षिप्त है और मैं एलडीएपी के साथ ही वसंत के लिए नया हूं। मैं यह सुनिश्चित करना चाहता हूं कि मैं आपकी टिप्पणी समझूं। यदि टैग हटाएं तो मैं मानक बाइंडिंग का उपयोग करने के लिए नीचे गिर जाऊंगा, क्योंकि उद्धृत जावा प्रोग्राम है और मैं बिल्कुल पासवर्ड तुलना नहीं करूँगा? क्या वसंत डिफ़ॉल्ट रूप से पासवर्ड तुलना करता है? क्या मुझे ऐसा करने के लिए कुछ सेट करने की आवश्यकता होगी? – Steve

+0

उनसे संपर्क करने का छोटा, आप नहीं कर सकते, और पासवर्ड की तुलना करना एक अच्छा विचार नहीं है अगर वे एन्कोड हैं (उदाहरण के लिए मामला अलग हो सकता है)। आपको बाइंड प्रमाणीकरण का उपयोग करना चाहिए क्योंकि आपने पहले ही प्रदर्शन किया है और काम की तुलना में भूल जाते हैं। आमतौर पर इसका उपयोग केवल तभी किया जाता है जब बांध अक्षम हो। क्या आपने प्रदान की गई कॉन्फ़िगरेशन का प्रयास किया था? यदि हां, तो क्या हुआ? –

+0

ल्यूक, आपकी टिप्पणियों के प्रकाश में मैंने अपना * server.xml और मेरी पूरी मूल पोस्ट बदल दी। मुझे थोड़ी देर के लिए अपनी विन्यास का अध्ययन करने की जरूरत है। यदि संभव हो तो मैं इसे स्प्रिंग 3.1 शैली लिखने का एक तरीका ढूंढना चाहता हूं। मैं इसे एक शॉट दूंगा और आपको बताऊंगा कि यह कैसे काम करता है। अनेक अनेक धन्यवाद। – Steve

0

मैं भाग्य की कोशिश करूंगा। कुछ हफ्ते पहले मुझे एक ही समस्या थी। कोई त्रुटि नहीं, सही उपयोगकर्ता/पास और खराब प्रमाण-पत्र त्रुटि।

सबसे पहले, मैं आपको वसंत सुरक्षा के लिए डीबग स्तर को सक्रिय करने की सलाह देता हूं। आपको और जानकारी मिल जाएगी। मेरे मामले में, इससे मुझे यह देखने में मदद मिली कि समस्या यह थी कि मेरे उपयोगकर्ता की कोई भूमिका नहीं थी और वसंत इसे "खराब प्रमाण-पत्र" त्रुटि के रूप में व्यापार कर रहा था। यह आपका मामला हो सकता है। इसे जाँचे।

वैसे भी, खराब प्रमाण-पत्र का मतलब हमेशा उपयोगकर्ता/गलत नहीं होता है।

संपादित करें: डिबग स्तर log4j का उपयोग कर सक्रिय करने के लिए:

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

आप विन्यास में, यह है कि एक्सेस पृष्ठ के स्वागत के लिए पढ़ा जा सकता है व्यवस्थापक भूमिका की आवश्यकता है: ROLE_ADMIN। आप भूमिकाओं नहीं करना चाहते हैं, तो आप कुछ इस तरह की कोशिश करनी चाहिए:

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

मैं वसंत और एलडीएपी के लिए नया हूँ। मैं वसंत सुरक्षा में डीबग स्तर को कैसे सक्रिय कर सकता हूं? क्या उपयोगकर्ता के साथ कोई भूमिका संबद्ध नहीं करना संभव है और यदि ऐसा है तो कैसे? क्या मैं सिर्फ उपयोगकर्ता के साथ तटस्थ भूमिका जोड़ सकता हूं? हमारे पास वास्तव में उपयोगकर्ताओं के लिए भूमिका नहीं है। – Steve

+0

मैंने जवाब संपादित किया है। यदि आप भूमिका नहीं चाहते हैं, तो किसी को एक्सेस में शामिल न करें। – jddsantaella

+0

मैंने आपके द्वारा सुझाए गए नए पहुंच मान का प्रयास किया। कोई परिवर्तन नहीं होता है। मैंने उस लॉगर xml को ऊपर उद्धृत कहां रखा होगा? – Steve

संबंधित मुद्दे