android - एंड्रॉइड खाता प्रबंधक स्टोर प्रति ऑप/यूआईडी बेसिस पर OAuth Tokens स्टोर नहीं करना चाहिए?




security authentication (3)

क्या यह एक वैध / व्यावहारिक सुरक्षा चिंता है?

आधिकारिक ग्राहक ए के लिए, मेरा OAuth2 प्रदाता "सुपर" प्रकार / स्कोप टोकन जारी कर सकता है जो मेरे एपीआई के सार्वजनिक और निजी दोनों टुकड़ों तक पहुंच प्रदान करता है

सामान्य स्थिति में, आप कभी भी उस उपयोगकर्ता से गुप्त उपयोगकर्ता को दिए गए ऑथ टोकन पर भरोसा नहीं कर सकते। उदाहरण के लिए - उपयोगकर्ता रूट किए गए फोन को चला सकता है, और टोकन को पढ़ सकता है, जिससे आपके निजी एपीआई तक पहुंच प्राप्त हो सकती है। अगर उपयोगकर्ता के सिस्टम से समझौता किया गया था तो हमलावर (हमलावर इस मामले में टोकन को पढ़ सकता था)।

एक और तरीका रखो, ऐसी कोई भी चीज़ नहीं है जो "निजी" एपीआई है जो किसी भी प्रमाणीकृत उपयोगकर्ता के लिए एक ही समय में पहुंच योग्य है, इसलिए एंड्रॉइड के लिए यह डिज़ाइन में अस्पष्टता लक्ष्य द्वारा इस सुरक्षा को अनदेखा करना उचित है।

एक दुर्भावनापूर्ण ऐप ... मेरे ऐप के संग्रहीत OAuth2 टोकन तक पहुंच प्राप्त कर सकता है

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

यह देखते हुए, एंड्रॉइड समाधान ठीक लगता है - ऐप्स चुपचाप उपयोगकर्ता के प्रमाणीकरण का उपयोग किए बिना चुपचाप उपयोग नहीं कर सकते हैं, लेकिन उपयोगकर्ता स्पष्ट रूप से किसी सेवा के लिए पिछले प्रमाणीकरण का पुन: उपयोग करने की अनुमति दे सकता है, जो उपयोगकर्ता के लिए सुविधाजनक है।

संभावित समाधान समीक्षा

"गुप्त" authTokenType ... बहुत सुरक्षित प्रतीत नहीं होता है

सहमत - यह अस्पष्टता के माध्यम से सुरक्षा की एक और परत है; ऐसा लगता है कि आपके प्रमाणीकरण को साझा करने की इच्छा रखने वाले किसी भी ऐप को यह देखना होगा कि ऑथन टोकन टाइप क्या था, इसलिए इस दृष्टिकोण को अपनाने से यह इस hypothetical ऐप डेवलपर के लिए थोड़ा और अजीब बनाता है।

क्लाइंट आईडी / गुप्त w / OAuth2 टोकन भेजें ... [से] सर्वर-पक्ष सत्यापित करें कि ऐप अधिकृत क्लाइंट है

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

सुझाव

आपने दो खतरों का वर्णन किया - दुर्भावनापूर्ण ऐप्स जो उपयोगकर्ता अपने खाते तक पहुंच नहीं लेना चाहते हैं, और वैकल्पिक क्लाइंट जिन्हें आप (डेवलपर) एपीआई के हिस्सों का उपयोग नहीं करना चाहते हैं।

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

  • वैकल्पिक ग्राहक: एक गुप्त एपीआई नहीं है जो केवल आधिकारिक ग्राहक के लिए सुलभ होने का प्रयास करता है; लोग इसके चारों ओर मिलेंगे। सुनिश्चित करें कि आपके सभी सार्वजनिक सामना करने वाले एपीआई सुरक्षित हैं चाहे उपयोगकर्ता (भविष्य) क्लाइंट का उपयोग कर रहे हों।

एंड्रॉइड का खाता प्रबंधक अलग-अलग यूआईडी वाले ऐप्स के लिए एक ही कैश किए गए ऑथ टोकन लाने के लिए प्रतीत होता है - क्या यह सुरक्षित है? यह OAuth2 के साथ संगत प्रतीत नहीं होता है, क्योंकि एक्सेस टोकन को विभिन्न ग्राहकों के बीच साझा नहीं किया जाना चाहिए।

पृष्ठभूमि / संदर्भ

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

मैं खाता प्रबंधन और डिवाइस पर संबंधित पहुंच टोकन के प्रबंधन के लिए खाता प्रबंधक का उपयोग कर रहा हूं। चूंकि मैं अपना खुद का OAuth2 प्रदाता प्रदान कर रहा हूं, इसलिए मैंने एंड्रॉइड देव गाइड में समझाया गया है और नमूना सिंक एडाप्टर नमूना प्रोजेक्ट में दिखाए गए अनुसार, एस्ट्रैक्ट अकाउंटिकेटर और अन्य आवश्यक घटकों को विस्तारित करके अपना स्वयं का कस्टम खाता प्रकार बनाया है। मैं अपने ऐप के भीतर से अपने कस्टम प्रकार के खातों को सफलतापूर्वक जोड़ सकता हूं और उन्हें "खाता और सिंक" एंड्रॉइड सेटिंग्स स्क्रीन से प्रबंधित कर सकता हूं।

समस्या

हालांकि, मैं खाता प्रबंधक कैश के तरीके से चिंतित हूं और ऑथ टोकन जारी करता हूं - विशेष रूप से, किसी दिए गए खाते के प्रकार और टोकन प्रकार के लिए एक ही ऑथ टोकन किसी भी ऐप द्वारा एक्सेस किया जा सकता है जिस पर उपयोगकर्ता ने पहुंच प्रदान की है।

AccountManager के माध्यम से एक ऑथ टोकन प्राप्त करने के लिए, किसी को अन्य चीज़ों के साथ Account प्रबंधक , AccountManager.getAuthToken() को गुजरना होगा, Account उदाहरण उदाहरण के लिए authTokenType टोकन और वांछित authTokenType टोकन authTokenType प्राप्त करना होगा। यदि निर्दिष्ट खाता और authTokenType के लिए कोई ऑथ टोकन मौजूद है, और यदि उपयोगकर्ता ऐप को पहुंच प्रदान करता है (अनुदान "एक्सेस अनुरोध" स्क्रीन के माध्यम से) जिसने ऑथ टोकन अनुरोध किया है (ऐसे मामलों में जहां अनुरोध करने वाला ऐप का यूआईडी मेल नहीं खाता है प्रमाणीकरणकर्ता यूआईडी), तो टोकन वापस कर दिया जाता है। यदि मेरी व्याख्या की कमी है, तो यह सहायक ब्लॉग एंट्री इसे स्पष्ट रूप से समझाती है। उस पोस्ट के आधार पर, और खाता प्रबंधक और खाता AccountManagerService (एक आंतरिक वर्ग जो खाता प्रबंधक के लिए भारी भारोत्तोलन करता है) के स्रोत की जांच करने के बाद, ऐसा प्रतीत होता है कि प्रति औथ टोकन / खाता कॉम्बो द्वारा केवल 1 ऑथ टोकन संग्रहीत किया जाता है।

इसलिए, यह व्यवहार्य लगता है कि यदि किसी दुर्भावनापूर्ण ऐप को मेरे प्रमाणीकरणकर्ता द्वारा उपयोग किए गए खाता प्रकार और ऑथटोकन टाइप (ओं) को पता था, तो यह मेरे ऐप के संग्रहीत OAuth2 टोकन तक पहुंच प्राप्त करने के लिए AccountManager.getAuthToken () को आमंत्रित कर सकता है, यह मानते हुए कि उपयोगकर्ता दुर्भावनापूर्ण तक पहुंच प्रदान करता है एप्लिकेशन।

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

क्या मैं यहाँ कुछ दिख रहा हूँ? क्या मेरा विश्वास है कि प्रति-ऐप / यूआईडी आधार पर प्रत्येक टोकन को जारी किया जाना चाहिए (प्रत्येक ऐप एक विशिष्ट ग्राहक है) तर्कसंगत / व्यावहारिक है, या ऑथ-टोकन-प्रति-डिवाइस (प्रत्येक डिवाइस क्लाइंट है) मानक / स्वीकृत अभ्यास?

या क्या AccountManager / AccountManagerService AccountManager आसपास कोड / सुरक्षा प्रतिबंधों की मेरी समझ में कुछ दोष है, जैसे कि यह भेद्यता वास्तव में मौजूद नहीं है? मैंने AccountManager और मेरे कस्टम प्रमाणीकरणकर्ता के साथ उपरोक्त क्लाइंट ए / क्लाइंट बी परिदृश्य का परीक्षण किया है, और मेरा टेस्ट क्लाइंट ऐप बी, जिसमें एक अलग पैकेज स्कोप और यूआईडी है, वह ऑथ टोकन प्राप्त करने में सक्षम था जिसे मेरे सर्वर ने मेरे लिए जारी किया था टेस्ट क्लाइंट ऐप ए एक ही authTokenType (जिसके दौरान मुझे "एक्सेस अनुरोध" अनुदान स्क्रीन के साथ संकेत दिया गया था, जिसे मैंने मंजूरी दे दी है क्योंकि मैं एक उपयोगकर्ता हूं और इसलिए अनजान हूं ...)

संभव समाधान

ए। "सीक्रेट" ऑथ टोकन टाइप
authTokenType टोकन प्राप्त करने के लिए, authTokenType टोकन authTokenType को जाना जाना चाहिए; क्या authTokenType टाइप को क्लाइंट authTokenType प्रकार के रूप में माना जाना चाहिए, जैसे किसी दिए गए गुप्त टोकन प्रकार के लिए जारी एक टोकन केवल उन "अधिकृत" क्लाइंट ऐप्स द्वारा प्राप्त किया जा सकता है जो गुप्त टोकन प्रकार को जानते हैं? यह बहुत सुरक्षित प्रतीत नहीं होता है; रूट डिवाइस पर, सिस्टम के accounts डेटाबेस में authtokens तालिका के auth_token_type कॉलम की जांच करना संभव होगा और मेरे टोकन के साथ संग्रहीत AuthTokenType मानों की जांच करें। इस प्रकार, मेरे ऐप के सभी इंस्टॉलेशन (और डिवाइस पर प्रयुक्त किसी भी अधिकृत तृतीय-पक्ष ऐप्स) में "गुप्त" ऑथ टोकन प्रकारों का उपयोग एक केंद्रीय स्थान पर सामने आया होगा। कम से कम OAuth2 क्लाइंट आईडी / रहस्यों के साथ, भले ही उन्हें ऐप के साथ पैक किया जाना चाहिए, फिर भी वे अलग-अलग क्लाइंट ऐप्स के बीच फैले हुए हैं, और उन लोगों को हतोत्साहित करने में मदद करने के लिए कुछ प्रयास किए जा सकते हैं (जो कुछ भी बेहतर नहीं है) ऐप को अनपॅक / डिकंपाइल करें।

ख। कस्टम ऑथ टोकन
AccountManager.KEY_CALLER_UID और AuthenticatorDescription.customTokens , और AccountManagerService स्रोत कोड के लिए दस्तावेज़ों के मुताबिक मैंने पहले संदर्भित किया था, मुझे यह निर्दिष्ट करने में सक्षम होना चाहिए कि मेरा कस्टम खाता प्रकार "कस्टम टोकन" का उपयोग करता है और मेरे कस्टम टोकन कैशिंग / स्टोरेज कार्यान्वयन को मेरे रिवाज में स्पिन करता है प्रमाणीकरणकर्ता, जिसमें मैं कॉलिंग ऐप के यूआईडी को प्रति-यूआईडी आधार पर ऑर्डर स्टोर / लाउथ ऑथ टोकन प्राप्त कर सकता हूं। असल में, मेरे पास डिफ़ॉल्ट कार्यान्वयन की तरह एक authtokens टेबल होगी, सिवाय इसके कि वहां एक जोड़ा uid कॉलम होगा ताकि टोकन को यूआईडी, अकाउंट, और ऑथ टोकन टाइप (केवल खाता और ऑथ टोकन टाइप के विपरीत) पर विशिष्ट रूप से अनुक्रमित किया जा सके। यह "गुप्त" ऑथ टोकन टाइप्स का उपयोग करने से अधिक सुरक्षित समाधान की तरह प्रतीत होता है, क्योंकि इसमें मेरे ऐप / प्रामाणिकता के सभी इंस्टॉलेशन में एक ही authTokenTypes का उपयोग करना शामिल होगा, जबकि authTokenTypes सिस्टम-टू-सिस्टम से भिन्न होते हैं, और आसानी से खराब नहीं किया जा सकता है। सुरक्षा के संदर्भ में इस दृष्टिकोण के लिए क्या डाउनसाइड्स हैं, मेरे खुद के टोकन कैशिंग तंत्र को लिखने और प्रबंधित करने के आनंददायक उपरांत के अलावा? क्या यह अधिक है? क्या मैं वास्तव में कुछ भी सुरक्षित कर रहा हूं, या क्या मुझे ऐसा कुछ याद आ रहा है कि यहां तक ​​कि इस तरह के कार्यान्वयन के साथ भी, एक दुर्भावनापूर्ण ऐप क्लाइंट के लिए अभी भी एक आसान ऐप क्लाइंट का authTokenType टोकन प्राप्त करने के लिए पर्याप्त होगा, जो authTokenType AccountManager और authTokenType टोकन authTokenType (एस) का उपयोग कर नहीं है गुप्त होने की गारंटी है (यह मानते हुए कि दुर्भावनापूर्ण ऐप OAuth2 क्लाइंट रहस्य को नहीं जानता है, और इसलिए सीधे ताजा टोकन नहीं मिल सकता है, लेकिन केवल अधिकृत ऐप क्लाइंट की ओर से AccountManager में कैश किए गए एक को प्राप्त करने की उम्मीद कर सकता है)?

सी। ग्राहक आईडी / गुप्त w / OAuth2 टोकन भेजें
मैं AccountManagerService के डिफ़ॉल्ट टोकन स्टोरेज कार्यान्वयन के साथ चिपक सकता हूं और अपने ऐप के ऑथ टोकन में अनधिकृत पहुंच की संभावना को स्वीकार कर सकता हूं, लेकिन मैं एक्सेस टोकन के अतिरिक्त, OAuth2 क्लाइंट आईडी और क्लाइंट राइट को हमेशा शामिल करने के लिए एपीआई अनुरोधों को मजबूर कर सकता हूं, और सर्वर-पक्ष सत्यापित करें कि ऐप अधिकृत क्लाइंट है जिसके लिए टोकन पहली जगह जारी किया गया था। हालांकि, मैं इससे बचना चाहूंगा क्योंकि ए) AFAIK, OAuth2 spec को संरक्षित संसाधन अनुरोधों के लिए क्लाइंट प्रमाणीकरण की आवश्यकता नहीं है - केवल एक्सेस टोकन आवश्यक है, और बी) मैं प्रत्येक पर क्लाइंट को प्रमाणीकृत करने के अतिरिक्त ओवरहेड से बचना चाहता हूं निवेदन।

सामान्य मामले में यह संभव नहीं है (सभी सर्वर प्रोटोकॉल में संदेशों की एक श्रृंखला है - उन संदेशों को उत्पन्न करने वाले कोड को निर्धारित नहीं किया जा सकता है)। - Michael

लेकिन ओएथ 2 प्रवाह में शुरुआती क्लाइंट प्रमाणीकरण के बारे में भी यही कहा जा सकता है, जिसके दौरान क्लाइंट को पहली बार एक्सेस टोकन जारी किया जाता है। केवल अंतर यह है कि केवल टोकन अनुरोध पर प्रमाणीकरण करने के बजाय, सुरक्षित संसाधनों के अनुरोध भी उसी तरह प्रमाणित किए जाएंगे। (ध्यान दें कि क्लाइंट ऐप AccountManager.getAuthToken() के loginOptions पैरामीटर के माध्यम से अपने क्लाइंट आईडी और क्लाइंट रहस्य में गुजरने में सक्षम होगा, जो मेरा कस्टम प्रमाणीकरण केवल OAuth2 प्रोटोकॉल के अनुसार मेरे संसाधन प्रदाता को पास करेगा)।

मुख्य सवाल

  1. क्या वास्तव में एक ऐप के लिए एक और ऐप प्राप्त करने के लिए खाता खोलने के लिए खातामैनगर.getAuthToken () को उसी खाते के साथ प्राप्त करना संभव है?
  2. यदि यह संभव है, तो क्या यह OAuth2 संदर्भ में मान्य / व्यावहारिक सुरक्षा चिंता है?

    आप उस उपयोगकर्ता से गुप्त उपयोगकर्ता को दिए गए ऑथ टोकन पर भरोसा नहीं कर सकते ... इसलिए एंड्रॉइड के लिए यह डिज़ाइन में अस्पष्टता लक्ष्य द्वारा इस सुरक्षा को अनदेखा करना उचित है - Michael

    लेकिन - मैं उपयोगकर्ता (संसाधन मालिक) के बारे में चिंतित नहीं हूं, मेरी सहमति के बिना लेख टोकन प्राप्त करना; मैं अनधिकृत ग्राहकों (ऐप्स) के बारे में चिंतित हूं। यदि उपयोगकर्ता अपने संरक्षित संसाधनों का हमलावर बनना चाहता है, तो वह खुद को खटखटा सकता है। मैं कह रहा हूं कि यह संभव नहीं होना चाहिए कि कोई उपयोगकर्ता मेरे क्लाइंट ऐप को इंस्टॉल करता है, और अनजाने में, एक "imposter" क्लाइंट ऐप जो मेरे ऐप के ऑथ टोकन तक पहुंच प्राप्त करने में सक्षम है क्योंकि यह सही ऑथ टोकन टाइप में था और उपयोगकर्ता था पहुंच अनुरोध स्क्रीन की जांच करने के लिए बहुत आलसी / अनजान / पहुंचे। यह समानता थोड़ी अधिक हो सकती है, लेकिन मैं इसे "अस्पष्टता से सुरक्षा" नहीं मानता हूं कि मेरा स्थापित फेसबुक ऐप मेरे जीमेल ऐप द्वारा कैश किए गए ईमेल नहीं पढ़ सकता है, जो मेरे फोन (उपयोगकर्ता) से अलग है और कैश की जांच कर रहा है सामग्री खुद

    उपयोगकर्ता को आपके टोकन का उपयोग करने के लिए ऐप के लिए एक (एंड्रॉइड सिस्टम प्रदान किया गया) एक्सेस अनुरोध स्वीकार करने की आवश्यकता है ... यह देखते हुए कि एंड्रॉइड समाधान ठीक लगता है - ऐप चुपचाप बिना उपयोगकर्ता के प्रमाणीकरण का उपयोग कर सकता है - Michael

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

    • औसत उपयोगकर्ता इस निर्णय को सक्षम बनाने में सक्षम होने के लिए पर्याप्त सुरक्षा-जागरूक नहीं है। मुझे विश्वास नहीं है कि हमें एंड्रॉइड की एक्सेस अनुरोध स्क्रीन पर "अस्वीकार" टैप करने के लिए उपयोगकर्ता के फैसले पर निर्भर होना चाहिए ताकि कच्चे फिशिंग प्रयास को भी रोका जा सके। जब उपयोगकर्ता को एक्सेस अनुरोध के साथ प्रस्तुत किया जाता है, तो मेरा प्रमाणीकरणकर्ता सभी प्रकार के संवेदनशील संरक्षित संसाधनों (जो केवल मेरा ग्राहक एक्सेस करने में सक्षम होना चाहिए) के लिए विस्तृत-विस्तृत और गणना कर सकता है जिसके लिए उपयोगकर्ता इसे प्रदान करेगा, वह अनुरोध स्वीकार कर लेगा, और ज्यादातर मामलों में, उपयोगकर्ता अभी भी बहुत अनजान होगा और स्वीकार करने जा रहा है। और दूसरे में, अधिक परिष्कृत फ़िशिंग प्रयासों, "imposter" ऐप उपयोगकर्ता के लिए एक्सेस अनुरोध स्क्रीन पर भौहें उठाने के लिए भी "आधिकारिक" दिखने जा रहा है। या, यहां एक और अधिक उदाहरण है - एक्सेस अनुरोध स्क्रीन पर, मेरा प्रमाणीकरणकर्ता बस इतना कह सकता है, "इस अनुरोध को स्वीकार न करें! अगर आप यह स्क्रीन देख रहे हैं, तो एक दुर्भावनापूर्ण ऐप आपके खाते तक पहुंच प्राप्त करने का प्रयास कर रहा है!" उम्मीद है कि, इस तरह के मामले में, अधिकांश उपयोगकर्ता अनुरोध से इंकार करेंगे। लेकिन - इसे अब तक क्यों जाना चाहिए? यदि एंड्रॉइड ने केवल प्रत्येक ऐप / यूआईडी के दायरे से अलग ऑथ टोकन रखा है जिसके लिए उन्हें जारी किया गया था, तो यह एक गैर-मुद्दा होगा। आइए सरलीकृत करें - यहां तक ​​कि उस मामले में जहां मेरे पास सिर्फ एक "आधिकारिक" क्लाइंट ऐप है, और इसलिए मेरा संसाधन प्रदाता अन्य डेवलपर्स के रूप में अन्य, तृतीय-पक्ष क्लाइंट को टोकन जारी करने की चिंता भी नहीं करता है, मेरे पास कहने का विकल्प होना चाहिए खाता प्रबंधक, "नहीं! इस लेख टोकन को लॉक-डाउन करें ताकि केवल मेरे ऐप तक पहुंच हो।" अगर मैं "कस्टम टोकन" मार्ग के साथ जाता हूं, तो मैं यह कर सकता हूं, लेकिन उस स्थिति में भी, मैं उपयोगकर्ता को एक्सेस अनुरोध स्क्रीन के साथ प्रस्तुत करने से पहले नहीं रोक पाऊंगा। कम से कम, यह बेहतर दस्तावेज होना चाहिए कि AccountManager.getAuthToken () का डिफ़ॉल्ट कार्यान्वयन सभी अनुरोध करने वाले ऐप्स / यूआईडी के लिए समान ऑथ टोकन लौटाएगा।
    • यहां तक ​​कि एंड्रॉइड दस्तावेज़ ओएथ 2 को प्रमाणीकरण (और संभावित रूप से प्राधिकरण) के लिए " उद्योग मानक " के रूप में भी पहचानते हैं। OAuth2 spec स्पष्ट रूप से बताता है कि एक्सेस टोकन को ग्राहकों के बीच साझा नहीं किया जाना चाहिए या किसी भी तरह से प्रकट नहीं किया जाना चाहिए। फिर, डिफ़ॉल्ट खाता प्रबंधक लागू करने / कॉन्फ़िगरेशन क्लाइंट के लिए एक ही कैश किए गए ऑथ टोकन को प्राप्त करना इतना आसान बनाता है जिसे मूल रूप से किसी अन्य क्लाइंट द्वारा सेवा से प्राप्त किया गया था? खाता प्रबंधक के भीतर एक साधारण फिक्स केवल उसी ऐप / यूआईडी के लिए कैश किए गए टोकन का पुन: उपयोग करना होगा जिसके तहत उन्हें मूल रूप से सेवा से प्राप्त किया गया था। यदि किसी दिए गए यूआईडी के लिए स्थानीय रूप से कैश किए गए ऑथ टोकन उपलब्ध नहीं हैं, तो इसे सेवा से प्राप्त किया जाना चाहिए। या कम से कम डेवलपर के लिए यह एक विन्यास योग्य विकल्प बनाओ।
    • ओएथ 3-पायदान वाले प्रवाह (जिसमें उपयोगकर्ता को क्लाइंट तक पहुंच प्रदान करना शामिल है) में, यह सेवा / संसाधन प्रदाता (और नहीं, कहें, ओएस) होना चाहिए जो ए को प्राप्त करता है) क्लाइंट और बी प्रमाणित करें ) यदि ग्राहक मान्य है, तो उपयोगकर्ता को अनुदान पहुंच अनुरोध के साथ प्रस्तुत करें? ऐसा लगता है कि एंड्रॉइड (गलत तरीके से) प्रवाह में इस भूमिका का उपयोग कर रहा है।

    लेकिन उपयोगकर्ता स्पष्ट रूप से ऐप्स को पिछले प्रमाणीकरण को किसी सेवा में पुन: उपयोग करने की अनुमति दे सकता है, जो उपयोगकर्ता के लिए सुविधाजनक है .-- Michael

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

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

    [उपयोग] वैकल्पिक ग्राहकों के पास एक गुप्त एपीआई नहीं है जो केवल आधिकारिक ग्राहक के लिए सुलभ होने का प्रयास करता है; लोग इसके चारों ओर मिलेंगे। सुनिश्चित करें कि आपके सभी सार्वजनिक सामना करने वाले एपीआई सुरक्षित हैं चाहे कोई भी (भविष्य) ग्राहक जो उपयोगकर्ता उपयोग कर रहा हो - Michael

    लेकिन - क्या यह पहली जगह ओएथ 2 का उपयोग करने के प्रमुख उद्देश्यों में से एक को पराजित नहीं करता है? प्रमाणीकरण क्या अच्छा है यदि सभी संभावित प्राधिकरण सुरक्षित संसाधनों के समान दायरे के लिए अधिकृत होंगे?

  4. क्या किसी और ने महसूस किया है कि यह एक मुद्दा था, और इसके आसपास आपका काम कैसा रहा? मैंने कुछ व्यापक गोगलिंग किया है ताकि यह पता लगाने के लिए कि क्या दूसरों ने इसे सुरक्षा समस्या / चिंता के रूप में महसूस किया है, लेकिन ऐसा लगता है कि एंड्रॉइड के खाता प्रबंधक और ऑथ टोकन से जुड़े अधिकांश पोस्ट / प्रश्न Google खाते के साथ प्रमाणित करने के बारे में हैं, न कि एक कस्टम खाता प्रकार और OAuth2 प्रदाता के साथ। इसके अलावा, मुझे ऐसे किसी भी व्यक्ति को नहीं मिला जो अलग-अलग ऐप्स द्वारा उपयोग किए जाने वाले एक ही ऑथ टोकन की संभावना के बारे में सोच रहा था, जो मुझे आश्चर्यचकित करता है कि यह वास्तव में पहली जगह में चिंता का विषय / योग्यता है (मेरा पहला 2 "मुख्य प्रश्न देखें " ऊपर सूचीबद्ध)।

मैं आपके इनपुट / मार्गदर्शन की सराहना करता हूं!

के जवाब में...

Michael - मुझे लगता है कि आपके उत्तर के साथ मेरी बड़ी समस्याएं हैं:

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

    उपयोगकर्ता रूट किए गए फोन को चला सकता है, और टोकन को पढ़ सकता है, अपने निजी एपीआई तक पहुंच प्राप्त कर सकता है ... [या] अगर उपयोगकर्ता के सिस्टम से समझौता किया गया था (हमलावर इस मामले में टोकन को पढ़ सकता था)

    और इसलिए, चीजों की भव्य योजना में, हमें डिवाइस को सेवा का ग्राहक मानना ​​चाहिए क्योंकि हम डिवाइस पर ऐप्स के बीच सुरक्षा की गारंटी नहीं दे सकते हैं। यह सच है अगर सिस्टम से समझौता किया गया है, तो उस डिवाइस से सेवा में भेजे जाने वाले अनुरोधों को प्रमाणित / अधिकृत करने की कोई गारंटी नहीं हो सकती है। लेकिन कहने के लिए कहा जा सकता है, टीएलएस; यदि परिवहन अंतराल सुरक्षित नहीं किया जा सकता है तो परिवहन सुरक्षा अप्रासंगिक है। और एंड्रॉइड डिवाइसों के विशाल बहुमत के लिए, जिनके साथ समझौता नहीं किया गया है, मेरा मानना ​​है कि प्रत्येक ऐप क्लाइंट को एक अलग एंडपॉइंट के रूप में विचार करना अधिक सुरक्षित है, बजाय उन्हें एक ही ऑथ टोकन साझा करके सभी को एक साथ लंपने के बजाय।

  2. "एक्सेस अनुरोध" स्क्रीन के साथ प्रस्तुत किए जाने पर (सॉफ़्टवेयर उपयोगकर्ता लाइसेंस अनुबंध के समान जो हम हमेशा सहमति और इंस्टॉल करने से पहले पूरी तरह से पढ़ते हैं), मुझे किसी दुर्भावनापूर्ण / अनधिकृत क्लाइंट ऐप को अलग करने के लिए उपयोगकर्ता के फैसले पर भरोसा नहीं है।

आपका अवलोकन सही है। प्रमाणीकरणकर्ता इंस्टॉलिंग ऐप के समान यूआईडी के साथ चलाएगा। जब कोई अन्य ऐप खाता प्रबंधक से जुड़ता है और इस प्रमाणीकरणकर्ता के लिए टोकन प्राप्त करता है, तो यह आपके प्रदत्त प्रमाणीकरण सेवा से जुड़ जाएगा। यह आपके यूआईडी के रूप में चलाएगा, इसलिए नए खाते इस प्रमाणीकरण से संबंधित होंगे। जब ऐप GetAuthToken के लिए कॉल करता है, बाध्यकारी होगा और प्रमाणीकरणकर्ता अभी भी उसी UID में चलाएगा। डिफ़ॉल्ट रूप से अनुमतियों में निर्मित खाता के यूआईडी के लिए जांच करें, ताकि विभिन्न प्रमाणीकरणकर्ता विभिन्न प्रमाणीकरणकर्ता से दूसरे खाते तक नहीं पहुंच सके।

खाता प्रबंधक सेवा बंडल करने के लिए जोड़ता है क्योंकि आप addAccount और GetAuthToken के लिए "कॉलिंग यूआईडी" का उपयोग करके इस समस्या को हल कर सकते हैं। आपका प्रमाणीकरण कार्यान्वयन उसको देख सकता है।

   @Override
    public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
            String authTokenType, Bundle loginOptions) throws NetworkErrorException {
        Log.v(
                TAG,
                "getAuthToken() for accountType:" + authTokenType + " package:"
                        + mContext.getPackageName() + "running pid:" + Binder.getCallingPid()
                        + " running uid:" + Binder.getCallingUid() + " caller uid:"
                        + loginOptions.getInt(AccountManager.KEY_CALLER_UID));
          ...
}

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

जब आप कोई खाता जोड़ रहे हों, तो आप कॉलिंगयूआईडी से भी पूछ सकते हैं। आपको अपनी ऐड खाता संबंधित गतिविधि पर यूज़रडेटा सेट करने की आवश्यकता है जो आपके ऐप के यूआईडी के रूप में चल रहा है, इसलिए यह setUserData को कॉल कर सकता है।

getUserData और setUserData SQLite डेटाबेस में निर्मित का उपयोग करता है, इसलिए आपको अपने आप से कैश बनाने की आवश्यकता नहीं है। आप केवल स्ट्रिंग प्रकार को स्टोर कर सकते हैं, लेकिन आप जेसन को पार्स कर सकते हैं और प्रति खाता अतिरिक्त जानकारी स्टोर कर सकते हैं।

जब विभिन्न तृतीय पक्ष ऐप प्रश्न खाते हैं और आपके खाते के साथ प्राप्त करने के लिए कॉल करते हैं, तो आप 'userdata' खाते में यूआईडी की जांच कर सकते हैं। यदि यूआईडी को कॉल नहीं किया गया है, तो आप अनुमति प्राप्त करने के लिए प्रॉम्प्ट और / या अन्य चीजें कर सकते हैं। यदि इसकी अनुमति है, तो आप खाते में नया यूआईडी जोड़ सकते हैं।

ऐप्स के बीच टोकन साझा करना : प्रत्येक ऐप आमतौर पर विभिन्न क्लाइंट के साथ पंजीकृत होता है और उन्हें टोकन साझा नहीं करना चाहिए। टोकन क्लाइंट ऐप के लिए है।

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


मुझे लगता है कि @ माइकल ने पूरी तरह से सवाल का जवाब दिया; हालांकि, उत्तर को और अधिक समझदार और त्वरित जवाब देने वाले लोगों को कम करने के लिए मैं इसे लिख रहा हूं।

एंड्रॉइड AccountManager की सुरक्षा के बारे में आपकी चिंता सही है, लेकिन AccountManager का यही अर्थ है, जिस पर एंड्रॉइड AccountManager निर्भर करता है।

दूसरे शब्दों में, यदि आप एक बहुत ही सुरक्षित प्रमाणीकरण तंत्र की तलाश में हैं तो यह आपके लिए एक अच्छा विकल्प नहीं होगा। आपको प्रमाणीकरण के लिए किसी भी कैश किए गए टोकन पर भरोसा नहीं करना चाहिए, क्योंकि अगर घुसपैठ करने वाले व्यक्ति को अनजाने में प्रवेश अनुमति प्रदान करना, जड़ डिवाइस चलाने, इत्यादि के मामले में किसी भी सुरक्षा भेद्यता के मामले में घुसपैठ करने वालों को आसानी से पता चला जा सकता है।

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

वैसे भी, अगर कोई एंड्रॉइड की AccountManager प्रणाली का उपयोग करना चाहता है और उच्च स्तर की सुरक्षा बनाए रखना चाहता है, तो डिवाइस पर किसी भी टोकन को सहेजना संभव नहीं होगा। getAuthToken से getAuthToken विधि को इस प्रकार ओवरराइड किया जा सकता है:

@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String
        authTokenType, Bundle options) throws NetworkErrorException {
    AuthenticatorManager authenticatorManager = AuthenticatorManager.authenticatorManager;
    Bundle result;
    AccountManager accountManager = AccountManager.get(context);
    // case 1: access token is available
    result = authenticatorManager.getAccessTokenFromCache(account, authTokenType,
            accountManager);
    if (result != null) {
        return result;
    }
    final String refreshToken = accountManager.getPassword(account);
    // case 2: access token is not available but refresh token is
    if (refreshToken != null) {
        result = authenticatorManager.makeResultBundle(account, refreshToken, null);
        return result;
    }
    // case 3: neither tokens is available but the account exists
    if (isAccountAvailable(account, accountManager)) {
        result = authenticatorManager.makeResultBundle(account, null, null);
        return result;
    }
    // case 4: account does not exist
    return new Bundle();
}

इस विधि में, न तो मामला 1, मामला 2 और न ही मामला 4 सच है क्योंकि कोई सहेजा गया टोकन नहीं है, भले ही account वहां है। इसलिए, केवल केस 3 वापस कर दिया जाएगा जिसे प्रासंगिक Activity लिए प्रासंगिक कॉलबैक में सेट किया जा सकता है जिसमें उपयोगकर्ता प्रमाणीकरण के लिए उपयोगकर्ता नाम और पासवर्ड दर्ज करता है।

मुझे इस बारे में और वर्णन करने के लिए सही रास्ते पर होने का यकीन नहीं है, लेकिन AccountManager पर मेरी वेबसाइट पोस्ट केवल मामले में मदद कर सकती है।





accountmanager