2011-05-31 8 views
14

जावा एसई 6 दस्तावेज से ओरेकल के "Http Authentication" पृष्ठ का कहना है कि "यदि आप एक डोमेन उपयोगकर्ता के रूप में एक विंडोज मशीन पर चल रहे हैं, या आप एक लिनक्स या सोलारिस मशीन पर चल रहे हैं जो पहले से ही kinit कमांड जारी कर चुका है और उसे क्रेडेंशियल कैश मिला है "तो उदाहरण Authenticator.setDefault() को पारित किया गया" पूरी तरह से अनदेखा किया जाएगा "।क्या जावा पर 'सिंगल साइन-ऑन' (विंडोज़ पर 'क्रेडेंशियल मैनेजर' से क्रेडेंशियल्स का उपयोग अक्षम किया जा सकता है?

यह मैंने जो देखा है उससे मेल खाता है: एक्स को होस्ट करने के लिए विंडोज सिस्टम पर एक HTTP या HTTPS कनेक्शन स्थापित करना हमेशा विंडोज़ विंडोज़ में 'विंडोज वॉल्ट' के 'विंडोज प्रमाण पत्र' से होस्ट एक्स के लिए प्रमाण पत्र पास करता है, जैसा कि मेरे विंडोज 7 में देखा गया है 'प्रमाण पत्र प्रबंधक' नियंत्रण कक्ष पृष्ठ।

हालांकि, मेरे उपयोग के मामले में मैं नहीं चाहता कि Windows द्वारा संग्रहित किया जा सकता है जो किसी भी क्रेडेंशियल्स का उपयोग करना चाहते हैं, लेकिन इसके बजाय मैं हमेशा साख मैं स्पष्ट रूप से कोड में निर्दिष्ट उपयोग करना चाहते हैं।

क्या दस्तावेजी व्यवहार को ओवरराइड करने का कोई तरीका है, यानी, क्या विंडोज द्वारा संग्रहीत क्रेडेंशियल्स को अनदेखा करने का कोई तरीका है?

अद्यतन: यदि नहीं, तो क्या कोई मुझे जावा एसई 6 स्रोत कोड में किसी स्थान पर इंगित कर सकता है जहां मैं देख सकता हूं कि संग्रहीत विंडोज प्रमाण-पत्रों को अनदेखा नहीं किया जा सकता है?

+0

आप कोड को पा सकते हैं जो 'sun.net.www.protocol.http.HttpURLConnection' क्लास पर Windows Credentials का उपयोग करते हुए मान्य करता है। 'NTLMAuthentication' उदाहरणों और ध्वज 'tryTransparentNTLMServer' के निर्माण पर एक नज़र डालें।मैं आपके जैसा ही काम करना चाहता हूं, लेकिन मुझे यकीन नहीं है कि यह कैसे करना है। – jmend

उत्तर

6

मैंने वही चीज़ देखी है जो आप पूछ रहे हैं। अब तक, मुझे ऐसा करने के लिए जेडीके पर कोई रास्ता नहीं मिला है।

जावा बग डेटाबेस पर वृद्धि के लिए अनुरोध है। यह पता लगाने के लिए report पर एक नज़र डालें कि क्या उसे सूर्य से प्रतिक्रिया मिलती है (रिपोर्ट को वोट दें ताकि आशा है कि जल्द ही ठीक हो जाए)।

मैं क्या कर रहा था, sun.net.www.protocol.http.NTLMAuthentication कक्षा ओवरराइड था। sun.net.www.protocol.http.HttpURLAuthentication को देख कर, मैंने पाया कि केवल एक चीज आप संशोधित करने की जरूरत का परिणाम है:

NTLMAuthentication.supportsTransparentAuth() 
विंडोज प्लेटफॉर्म पर

विधि एक हार्डकोडेड वापसी मूल्य होता है, true और false अन्यथा। इस कोड को एक JDK विंडोज 7 पर स्थापित से निकाला जाता है:

static boolean supportsTransparentAuth() 
{ 
    return true; 
} 

क्या उस विधि बताता है विंडोज साख डिफ़ॉल्ट रूप से इस्तेमाल किया जाना चाहिए है। यदि true पर सेट किया गया है, आपके कस्टम प्रमाणीकरण कोड को नहीं कहा जाएगा। HttpURLConnection वर्ग के इस टुकड़ा देखें:

//Declared as a member variable of HttpURLConnection 
private boolean tryTransparentNTLMServer = NTLMAuthentication.supportsTransparentAuth(); 

//Inside of getServerAuthentication method. 
PasswordAuthentication a = null; 
if (!tryTransparentNTLMServer) { 
    //If set to false, this will call Authenticator.requestPasswordAuthentication(). 
    a = privilegedRequestPasswordAuthentication(url.getHost(), addr, port, url.getProtocol(), "", scheme, url, RequestorType.SERVER); 
} 

/* If we are not trying transparent authentication then 
* we need to have a PasswordAuthentication instance. For 
* transparent authentication (Windows only) the username 
* and password will be picked up from the current logged 
* on users credentials. 
*/ 
if (tryTransparentNTLMServer || (!tryTransparentNTLMServer && a != null)) { 
    //If set to true or if Authenticator did not return any credentials, use Windows credentials. 
    //NTLMAuthentication constructor, if receives a == null will fetch current looged user credentials. 
    ret = new NTLMAuthentication(false, url1, a); 
} 

NTLMAuthentication स्रोत कोड प्राप्त करने के लिए, मैं this Java decompiler इस्तेमाल किया। जेडीके स्थापना फ़ोल्डर पर स्थित rt.jar खोला और वांछित कक्षा कोड की प्रतिलिपि बनाई।

फिर, मैंने झूठी वापसी के लिए supportsTransparentAuth को बदल दिया। हालांकि, यह बहुत वांछनीय होगा यदि इस विधि ने पहले सिस्टम प्रॉपर्टी की जांच की और फिर उस पर आधारित सही या गलत लौटा दिया।

यह संकलन करने के लिए, मैं सिर्फ जावा फ़ाइल के नीचे धूप/नेट/www/प्रोटोकॉल/http फ़ोल्डर संरचना रखा जाता है और चलाएँ:

javac NTLMAuthentication.java 

तब का उपयोग कर अपने आवेदन चलाएँ:

java -Xbootclasspath:"path/to/your/sun/net/www/protocol/http/classes;normal/JDK/boot/directories" 

कि rt.jar में से पहले NTLMAuthentication के हमारे कार्यान्वयन को लोड करने के लिए जेवीएम को बताएगा। -Xbootclasspath के साथ किसी भी डिफ़ॉल्ट वर्ग लोडिंग पथ को याद न करने के लिए आपको सावधान रहना होगा, या ClassNotFound त्रुटियां होंगी।

उसके बाद, सबकुछ ठीक काम करता था।

इस दृष्टिकोण में महत्वपूर्ण कमीएं हैं जिनके बारे में आपको अवगत होना चाहिए।

  • सुरक्षा जोखिम हैं। कोई भी आपके बूट फ़ोल्डर पर एक अलग .class फ़ाइल छोड़ सकता है और उपयोगकर्ता प्रमाण-पत्र या अन्य महत्वपूर्ण जानकारी चुरा सकता है।
  • सूर्य पैकेज से कोड बिना किसी सूचना के बदल सकते हैं और इस प्रकार आपके परिवर्तनों के साथ असंगत हो सकते हैं।
  • यदि आप इस कोड को तैनात करते हैं, तो आप सूर्य कोड लाइसेंस का उल्लंघन करेंगे। documentation से:

-Xbootclasspath: bootclasspath निर्देशिका, जार अभिलेखागार के एक अर्धविराम द्वारा अलग किए सूची निर्दिष्ट करें, और बूट वर्ग फ़ाइलों के लिए खोज करने के लिए अभिलेखागार ज़िप। इन्हें जावा 2 एसडीके में शामिल बूट क्लास फ़ाइलों के स्थान पर उपयोग किया जाता है। नोट: के प्रयोजन के लिए इस विकल्प का उपयोग करने वाले अनुप्रयोगों को rt.jar में किसी वर्ग को ओवरराइड करने के लिए तैनात नहीं किया जाना चाहिए, इसलिए जावा 2 रनटाइम पर्यावरण बाइनरी कोड लाइसेंस का उल्लंघन करेगा।

तो, यह निश्चित रूप से उत्पादन वातावरण के लिए उपयुक्त नहीं है। PDF

आशा इस मदद करता है:

अंत में, इस बारे में बूट वर्ग पथ विकल्प और जावा वर्ग लोडर बहुत अच्छा स्रोत है।

+0

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

+0

हां, उत्पादन के उपयोग के लिए यह निश्चित रूप से टाला जाना चाहिए। सौभाग्य से, मुझे बस एक डेमो के लिए इसकी आवश्यकता थी, इसलिए यह मेरे लिए काम किया। – jmend

+1

यदि कोई इस पर आता है, तो जावा अंतर्निहित [HTTP API] के बजाय [अपाचे HTTP क्लाइंट 4] (http://hc.apache.org/httpcomponents-client-ga/) का उपयोग करने में एक बहुत ही सरल दृष्टिकोण है (http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html)। मेरे विशेष मामले में, मैं [अपाचे HTTP क्लाइंट] (http://hc.apache.org/httpcomponents-client-ga/) और [जेसीआईएफ एनटीएलएम] के संयोजन का उपयोग करके समाप्त हुआ (http://jcifs.samba.org /src/docs/ntlmhttpauth.html) जावा में सभी एनटीएलएम संबंधित मुद्दों को हल करने के लिए कार्यान्वयन। – jmend

6

कम से कम जावा 7 में sun.net.www.protocol.http.ntlm.NTLMAuthenticationCallback नामक एक कक्षा है जो इस स्थिति में मदद करने के लिए प्रतीत होती है। एकल साइन-ऑन केवल "विश्वसनीय" यूआरएल के लिए बुलाया जाता है।

static { 
    NTLMAuthenticationCallback.setNTLMAuthenticationCallback(new NTLMAuthenticationCallback() 
    { 
     @Override 
     public boolean isTrustedSite(URL url) 
     { 
      return false; 
     } 
    }); 
} 

मुझे लगता है कि डिफ़ॉल्ट कार्यान्वयन पर भरोसा करने के लिए सब कुछ :(

+2

+1 के तहत ऐप चलाने के लिए अन्य विंडोज सुविधाओं का उपयोग कर सकता है। और हां, मैं [DefaultNTLMAuthenticationCallback] में देखता हूं (http://www.docjar.com/docs/api/sun/net/www/protocol/http/ntlm/NTLMA प्रमाणीकरण कॉलबैक $DefaultNTLMAuthenticationCallback.html#isTrustedSite%28URL%29) कि डिफ़ॉल्ट कार्यान्वयन चुप कोशिश करने के लिए है (जावाडॉक कॉल 'पारदर्शी') प्रमाणीकरण क्या है। –

2

ऐसा लगता है: (इस initialiser पहले HTTP कनेक्शन खोलने के लिए कहा जाता है)

यहाँ सबसे सरल कार्यान्वयन इसे बंद करने के लिए है कि क्लास sun.net.www.protocol.http.ntlm.NTLMAuthenticationCallback जावा 6.0 पैच 24+ में जोड़ा गया था, इसलिए समाधान का सुझाव जावा 6.0 में भी काम कर सकता है। निम्नलिखित पोस्ट में संदर्भ देखें: http://www.mail-archive.com/[email protected]/msg22897.html

+0

+1 धन्यवाद! कृपया ध्यान दें कि निर्दिष्ट पोस्ट कहता है कि जावा 6 पर पैकेज का नाम अलग है, जैसे। 'Sun.net.www.protocol.http'। –

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