2012-11-28 20 views
5

में HTTP प्रमाणीकरण चुनौतियों का जवाब कैसे दें मेरे ऐप में मैं HTTPS पर वेब सेवा पर HTTP कॉल करता हूं। मेरी इच्छा है कि मेरे क्लाइंट को इस तरह से डिजाइन करना है कि प्रमाणीकरण चुनौती होने पर यह केवल उपयोगकर्ता को उनके उपयोगकर्ता नाम और पासवर्ड के लिए पूछता है। मैं प्रतिक्रियाशील होना चाहता हूं, प्रीemptive नहीं। मेरे ऐप की प्रकृति के कारण, कुछ ऐसे मामले हैं जहां इसे प्रमाणित करने की आवश्यकता नहीं होगी।Android

आईओएस में, इस प्रक्रिया को NSURLConnectionDelegateProtocol के माध्यम से बहुत आसान बना दिया गया है, जो मेरे ऐप के आईओएस संस्करण में लागू किया गया है। इस वर्ग का उपयोग करके एक कनेक्शन बनाया जाता है, और केवल तभी जब एक चुनौती प्रस्तुत की जाती है, वर्ग कक्षा के प्रमाणीकरण प्रमाण-पत्रों के लिए अपने प्रतिनिधि से पूछता है।

एंड्रॉइड में यह कैसे किया जा सकता है? AuthenticationHandler का उपयोग करना? या शायद Authenticator? यदि ऐसा है, तो उदाहरण या ट्यूटोरियल प्रदान किया जा सकता है?

संपादित करें 1:

प्रमाणक वर्ग (नीचे मेरा उत्तर देखें) अब मैं चुनौतियों प्रमाणीकरण के लिए प्रतिक्रिया करने में सक्षम हूँ, लेकिन वर्तमान में केवल हार्ड-कोडेड पहचान के साथ उपयोग करना। मैं उपयोगकर्ता को उपयोगकर्ता नाम और पासवर्ड के लिए संकेत देना चाहता हूं। Android documentation के अनुसार, getPasswordAuthentication विधि के भीतर आप "आमतौर पर आवश्यक इनपुट के लिए उपयोगकर्ता को संकेत देते हैं"।

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

संपादित 2:

जबकि वहाँ थोड़ा हैं या प्रमाणक वर्ग के उपयोग पर कोई उदाहरण है, क्या मैं खोजने के लिए सक्षम किया गया है पता चलता है कि निवेश के लिए उपयोगकर्ता को संकेत एक एकल विधि के भीतर से असंभव है, getPasswordAuthentication की तरह। Apache HTTP ग्राहक के लिए वापस लौटने के लिए ... हो सकता है

अंतिम संपादित:

मैं अभी भी HttpURLConnection उपयोग कर रहा हूँ, लेकिन क्या एडवर्ड नीचे का सुझाव दिया की तर्ज पर कुछ कर रही। प्रमाणीकरण चुनौतियों को संभालने और इनपुट के लिए उपयोगकर्ता को संकेत देने के लिए कोई कॉन्फ़िगर करने योग्य वर्ग प्रतीत नहीं होता है, इसलिए मैं इसे मैन्युअल रूप से कर रहा हूं।

उत्तर

3

प्रमाणीकरण शीर्षलेख के बिना अपना अनुरोध भेजें। अगर प्रमाणीकरण की आवश्यकता है, तो कनेक्शन 401 त्रुटि के साथ विफल हो जाएगा। प्रारंभिक अनुरोध किए गए कोड को विफल करने के लिए उस विफलता को वापस ले जाएं। उस कोड को उपयोगकर्ता को प्रमाणीकरण संवाद दिखाना चाहिए। उपयोगकर्ता द्वारा प्रदान किए गए उपयोगकर्ता नाम/पासवर्ड को याद रखें, और अनुरोध में जोड़े गए आवश्यक प्रमाणीकरण शीर्षलेख के साथ विफल अनुरोध को पुनः प्रयास करें।

शेष सत्र के लिए उपयोगकर्ता नाम/पासवर्ड याद रखें ताकि आपको उपयोगकर्ता से पूछना न पड़े।

मुझे खेद है कि मेरे पास कोई नमूना कोड नहीं है; मैंने इसे java.net में कार्यान्वित किया है, लेकिन यदि आप अपाचे का उपयोग कर रहे हैं तो यह आपको कोई अच्छा नहीं करेगा।

यह धागा आप मदद कर सकते हैं: Http Basic Authentication in Java using HttpClient?

संपादित करें:

मैं java.net में यह लागू कर दिया है, लेकिन यह काम मैं भाड़े के लिए किया था और मैं स्रोत कोड के लिए पहुँच नहीं है।एक समस्या यह है कि java.net आपको प्रति कनेक्शन आधार पर प्रमाणीकरण सेट नहीं करने देता है, बल्कि इसके बजाय आप एक वैश्विक प्रमाणीकरण लागू करते हैं। चूंकि मेरा ऐप केवल एक विशिष्ट वेबसाइट के साथ संवाद करता है, यह कोई मुद्दा नहीं था।

मैंने जो किया वह Authenticator का उप-वर्ग बना था जो उपयोगकर्ता से उपयोगकर्ता नाम/पासवर्ड डेटा कैश करता था। कैश का प्रारंभिक मूल्य खाली था। एक "प्रयास काउंटर" भी है। जब प्रमाणीकरणकर्ता कहा जाता है और कोई कैश किए गए उपयोगकर्ता/पासवर्ड की जानकारी नहीं होती है, तो उपयोगकर्ता को एक संवाद के माध्यम से संकेत दिया जाता है। यदि कैश किए गए मान मौजूद हैं, तो वे उपयोगकर्ता को परेशान किए बिना वापस लौटाए जाते हैं।

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

प्रत्येक नए इंटरनेट कनेक्शन से पहले काउंटर रीसेट किया जाता है।

एक स्मार्ट प्रमाणीकरण मेजबान और/या दायरे (त्वरित स्ट्रिंग) पर ध्यान देना होगा और तदनुसार उपयोगकर्ता/पासवर्ड कैश करेगा।

मुझे यकीन नहीं है कि यह किसी भी एंड्रॉइड वातावरण में आपके लिए उपयोगी होगा, क्योंकि एक संवाद पॉप अप करने से आपके प्रमाणीकरणकर्ता के लिए एक विकल्प उपलब्ध नहीं हो सकता है। लेकिन मैं इसके बारे में गलत हो सकता था; यह आपके आवेदन पर निर्भर करता है।

एंड्रॉइड वातावरण में, आप अपने http अनुरोधों को थ्रेड से करना चाहते हैं और फिर डेटा आने पर गतिविधि को सिग्नल करना चाहते हैं। यदि आपका धागा 401 त्रुटि का पता लगाता है, तो यह गतिविधि को उस प्रभाव पर संकेत देगा, और फिर गतिविधि एक संवाद पॉप अप कर सकती है और थ्रेड को फिर से लॉन्च कर सकती है। धागा तब एक मामूली प्रमाणीकरणकर्ता पंजीकृत करेगा जो उपयोगकर्ता/पासवर्ड की जानकारी को वापस कर देता है। वैकल्पिक रूप से, थ्रेड मैन्युअल रूप से प्राधिकरण शीर्षलेख बना सकता है, हालांकि यह अधिक काम है।

  • अपाचे HTTP क्लाइंट
  • java.net HttpURLConnection

हाल ही में एक सिंहावलोकन:

+0

मैं java.net का उपयोग करने का भी प्रयास कर रहा हूं, क्योंकि ऐसा लगता है कि आगे बढ़ने वाला सबसे समर्थित विकल्प होगा। मैंने जो सुझाव दिया है उसे मैं कोशिश करूंगा। क्या आपने कभी प्रमाणीकरण वर्ग का उपयोग करने का प्रयास किया है? – Groppe

+0

उपरोक्त मेरे संपादन देखें। –

+0

धन्यवाद। मैंने जो पढ़ा है, उससे एक संवाद पॉप अप करना (जो मैं करना चाहता हूं) दुर्भाग्य से प्रमाणीकरणकर्ता के getPassword प्रमाणीकरण विधि के भीतर से संभव नहीं है। – Groppe

2

जो लोग नहीं जानते के लिए, वहाँ दो प्रमुख HTTP क्लाइंट एपीआई उपयोग के लिए उपलब्ध एंड्रॉयड में हैं इनमें से दोनों को Android Developers Blog post में दिया गया है।

क्योंकि, ब्लॉग के हवाले से मैं, java.net कार्यान्वयन उपयोग करने के लिए चुन लिया है: "। नए अनुप्रयोगों HttpURLConnection का उपयोग करना चाहिए, यह वह जगह है जहाँ हम आगे बढ़ते हुए अपनी ऊर्जा खर्च किया जाएगा" इसके अलावा, HttpURLConnection का उपयोग कर कनेक्ट करेगा एसएसएल स्वचालित रूप से प्रदान किया गया है अगर यूआरएल एचटीपीएस है। जैसा कि मैंने मूल पोस्ट में कहा था, मैं एपीआई के भीतर एक इंटरफेस की तलाश में था जो मुझे आवश्यक होने पर प्रमाणीकरण चुनौतियों को स्वचालित रूप से संभालने की अनुमति देगा। मैंने पाया है कि प्रमाणीकरण वर्ग जो मैं चाहता हूं वह करता है।

यहाँ कोड मैं अब तक है कि है, और यह काम करता है:

connection.setRequestProperty("Authorization", "Basic"); 
:

URL Url = new URL(url); 

Authenticator.setDefault(new Authenticator() { 
    protected PasswordAuthentication getPasswordAuthentication() { 
     return (new PasswordAuthentication("username", "password".toCharArray())); 
    } 
}); 

connection = (HttpURLConnection) Url.openConnection(); 
connection.setRequestProperty("Authorization", "Basic"); 

content = new BufferedInputStream(connection.getInputStream()); 
BufferedReader reader = new BufferedReader(new InputStreamReader(content)); 
String line; 
while ((line = reader.readLine()) != null) { 
    stringBuilder.append(line); 
} 

कुंजी (मेरे लिए) हो रही प्रमाणक की विधि वास्तव में कहा जा करने के लिए, इस लाइन था

अन्यथा, अनुरोध वास्तव में 200 (ठीक) की प्रतिक्रिया लौटाएगा, और मुझे लॉगिन पृष्ठ पर रीडायरेक्ट करेगा।

अगला चरण: ऊपर getPasswordAuthentication विधि से, उपयोगकर्ता को उपयोगकर्ता नाम और पासवर्ड के लिए संकेत दें, और किसी भी तरह इसे वापस कर दें। यदि आप इसके साथ मदद कर सकते हैं, तो जवाब पोस्ट करें!

+0

हे; प्रति दिन कुछ नया सीखें। मैंने पढ़ा था कि java.net को अप्रचलित माना गया था, जिसे जावाएमई के लिए विकसित किया गया था, और सभी को अपाचे क्लाइंट का उपयोग करना चाहिए। मैंने केवल उन परिस्थितियों में java.net का उपयोग किया है जहां अपाचे लाइब्रेरी अनुपलब्ध थी। मुझे लगता है कि यह वापस स्विच करने का समय है। –

+0

एडवर्ड, मैं अभी आपके द्वारा पूछे गए एक प्रश्न में आया (http://stackoverflow.com/questions/6100989/java-how-to-launch-a-ui-dialog-from-another-thread-eg-for-authenticator) , और जो उत्तर आप/एंड्रयू प्रदान करते हैं, वह अब मैं जो करने की कोशिश कर रहा हूं उसके आधार पर कहीं ऐसा लगता है। आपने एक टिप्पणी में कहा "मेरी इच्छा है कि जावा में एंड्रॉइड की संदेश-पासिंग सुविधा हो।" चूंकि हम अब एंड्रॉइड के बारे में बात कर रहे हैं, तो आप इसके बारे में कैसे जाने की सलाह देंगे? – Groppe

+0

अच्छा काम करने वाले लोग..मेरे पास एक जटिल आईओएस ऑथ प्रक्रिया है और मुझे नहीं पता था कि एंड्रॉइड में इसे कैसे किया जाए। मुझे आश्चर्य है कि आप दोनों के लिए और अधिक उत्साह नहीं हैं। मुझे एसएसएल पास करने के लिए un/pw स्टोर करना होगा और उसके बाद Windows प्रमाणीकरण चुनौती को पास करना होगा, इसलिए यह पोस्ट इस प्रकार की प्रक्रिया में मदद करता है। – whyoz