authentication - आरईएसटी एपीआई टोकन-आधारित प्रमाणीकरण




rest (2)

मैं एक आरईएसटी एपीआई विकसित कर रहा हूं जिसके लिए प्रमाणीकरण की आवश्यकता है। चूंकि प्रमाणीकरण स्वयं HTTP पर बाहरी webservice के माध्यम से होता है, इसलिए मैंने तर्क दिया कि हम बार-बार प्रमाणीकरण सेवा को कॉल करने से बचने के लिए टोकन वितरित करेंगे। जो मुझे अपने पहले प्रश्न पर अच्छी तरह से लाता है:

क्या यह वास्तव में क्लाइंट को प्रत्येक अनुरोध पर HTTP बेसिक एथ का उपयोग करने और प्रमाणीकरण सेवा सर्वर-साइड को कैशिंग कॉल करने की आवश्यकता से बेहतर है?

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

वर्तमान में टोकन इस तरह अधिग्रहित किए गए हैं:

curl -X POST localhost/token --data "api_key=81169d80...
                                     &verifier=2f5ae51a...
                                     &timestamp=1234567
                                     &user=foo
                                     &pass=bar"

सभी अनुरोधों द्वारा api_key , timestamp और verifier आवश्यक हैं। "सत्यापनकर्ता" द्वारा वापस किया जाता है:

sha1(timestamp + api_key + shared_secret)

मेरा इरादा केवल ज्ञात पार्टियों से कॉल की अनुमति देना है, और कॉल को पुन: उपयोग करने से रोकने के लिए है।

क्या यह काफी अच्छा है? Underkill? Overkill?

हाथ में टोकन के साथ, ग्राहक संसाधन प्राप्त कर सकते हैं:

curl localhost/posts?api_key=81169d80...
                    &verifier=81169d80...
                    &token=9fUyas64...
                    &timestamp=1234567

सबसे आसान कॉल संभव के लिए, यह बहुत ही भयंकर वर्बोज़ लगता है। shared_secret को ध्यान में रखते हुए एक आईओएस एप्लिकेशन (न्यूनतम) में एम्बेडेड किया जाएगा, जिससे मुझे लगता है कि इसे निकाला जा सकता है, क्या यह सुरक्षा की झूठी भावना से परे कुछ भी पेशकश कर रहा है?


एक शुद्ध रीस्टफुल एपीआई अंतर्निहित प्रोटोकॉल मानक सुविधाओं का उपयोग करना चाहिए:

  1. HTTP के लिए, RESTful API को मौजूदा HTTP मानक हेडर का अनुपालन करना चाहिए। एक नया HTTP शीर्षलेख जोड़ना आरईएसटी सिद्धांतों का उल्लंघन करता है। पहिया का पुन: आविष्कार न करें, HTTP / 1.1 मानकों में सभी मानक सुविधाओं का उपयोग करें - जिसमें स्टेटस प्रतिक्रिया कोड, हेडर आदि शामिल हैं। रीस्टफुल वेब सेवाओं को लाभ उठाना चाहिए और HTTP मानकों पर भरोसा करना चाहिए।

  2. विश्वसनीय सेवाओं को पूरा होना चाहिए। किसी भी चाल, जैसे कि टोकन आधारित प्रमाणीकरण जो सर्वर पर पिछले आरईएसटी अनुरोधों की स्थिति को याद रखने का प्रयास करता है, आरईएसटी सिद्धांतों का उल्लंघन करता है। फिर, यह एक जरूरी है; यानी, यदि आप वेब सर्वर सर्वर पर किसी भी प्रकार के सत्र को स्थापित करने के प्रयास में सर्वर पर कोई अनुरोध / प्रतिक्रिया संदर्भ संबंधित जानकारी सहेजता है, तो आपकी वेब सेवा स्टेटलेस नहीं है। और यदि यह स्टेटलेस नहीं है तो यह रीस्टफुल नहीं है।

निचली पंक्ति: प्रमाणीकरण / प्राधिकरण उद्देश्यों के लिए आपको HTTP मानक प्राधिकरण शीर्षलेख का उपयोग करना चाहिए। यही है, आपको प्रत्येक बाद के अनुरोध में HTTP प्रमाणीकरण / प्रमाणीकरण शीर्षलेख जोड़ना चाहिए जिसे प्रमाणीकृत करने की आवश्यकता है। आरईएसटी एपीआई को HTTP प्रमाणीकरण स्कीम मानकों का पालन करना चाहिए। इस हेडर को प्रारूपित करने के तरीके को निर्दिष्ट किया गया है आरएफसी 2616 HTTP 1.1 मानकों में परिभाषित किया गया है - खंड 14.8 आरएफसी 2616 का प्रमाणीकरण, और आरएफसी 2617 HTTP प्रमाणीकरण में: मूल और डाइजेस्ट एक्सेस प्रमाणीकरण ।

मैंने सिस्को प्राइम परफॉर्मेंस मैनेजर एप्लिकेशन के लिए एक शानदार सेवा विकसित की है। आरईएसटीएफआई एपीआई अनुपालन के बारे में अधिक जानकारी के लिए मैंने उस एप्लिकेशन के लिए आरईएसटी एपीआई दस्तावेज़ के लिए Google की खोज की here । उस कार्यान्वयन में, मैंने HTTP "बेसिक" प्राधिकरण योजना का उपयोग करना चुना है। - उस REST API दस्तावेज़ के संस्करण 1.5 या उससे ऊपर की जांच करें, और दस्तावेज़ में प्रमाणीकरण की खोज करें।


मुझे सब कुछ अलग करने दें और अलगाव में प्रत्येक समस्या को हल करने दें:

प्रमाणीकरण

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

ऑथ सर्वर लोड

यदि आप अपने सर्वर पर प्रमाणीकरण को कैश करने के बजाय उपयोगकर्ता को टोकन देते हैं, तो आप अभी भी वही कर रहे हैं: प्रमाणीकरण जानकारी कैशिंग। केवल अंतर यह है कि आप उपयोगकर्ता को कैशिंग की ज़िम्मेदारी बदल रहे हैं। ऐसा लगता है कि उपयोगकर्ता के लिए कोई लाभ नहीं होने के कारण अनावश्यक श्रम की तरह लगता है, इसलिए मैंने सुझाव दिया है कि आप अपने सर्वर पर पारदर्शी रूप से इसे संभालने की सलाह देते हैं।

ट्रांसमिशन सुरक्षा

यदि एक एसएसएल कनेक्शन का उपयोग कर सकते हैं, तो यह सब कुछ है, कनेक्शन सुरक्षित है *। आकस्मिक एकाधिक निष्पादन को रोकने के लिए, आप एकाधिक यूआरएल फ़िल्टर कर सकते हैं या यूआरएल में यादृच्छिक घटक ("nonce") शामिल करने के लिए उपयोगकर्ताओं से पूछ सकते हैं।

url = username:[email protected]/api/call/nonce

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

nonce = generate_secure_password(length: 16);
one_time_key = nonce + '-' + sha1(nonce+salt+shared_key);
url = username:[email protected]/api/call

यह सच है कि यह थोड़ा श्रमिक है। ऐसा इसलिए है क्योंकि आप प्रोटोकॉल स्तर समाधान (जैसे एसएसएल) का उपयोग नहीं कर रहे हैं। तो उपयोगकर्ताओं के लिए किसी प्रकार का एसडीके प्रदान करना एक अच्छा विचार हो सकता है ताकि कम से कम उन्हें खुद से गुजरना पड़े। यदि आपको ऐसा करने की ज़रूरत है, तो मुझे सुरक्षा स्तर उचित (बस-दाएं-मारना) मिल जाएगा।

सुरक्षित गुप्त भंडारण

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

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

(*) संपादित करें: एसएसएल कनेक्शन को सत्यापित करने के लिए अतिरिक्त कदम उठाए बिना सुरक्षित नहीं माना जाना चाहिए







rest