2012-11-06 13 views
5

मेरे पास Google App Engine पर दो ऐप्स हैं, दोनों एक ही खाते के अंतर्गत चल रहे हैं, और एक अन्य एचटीटीपीएस द्वारा प्रदान की जाने वाली सेवाओं को आमंत्रित करता है। यह सुनिश्चित करने का अनुशंसित तरीका क्या है कि केवल पहले ऐप को दूसरे को आमंत्रित करने की अनुमति है?Google ऐप इंजन: सुरक्षित इंटर-ऐप संचार

वैकल्पिक रूप से, क्या यह निर्दिष्ट करने का एक तरीका है कि दिए गए एंडपॉइंट को केवल उसी GAE खाते के अंतर्गत चल रहे ऐप द्वारा ही बुलाया जा सकता है?

उत्तर

3

क्या आपका आवेदन 'एक्स-एपेंगिन-इनबाउंड-एपिड' हेडर के लिए जांचें और सुनिश्चित करें कि ऐप आईडी सही है। यह हेडर केवल तभी मौजूद है जब अनुरोध किसी अन्य Google App Engine ऐप द्वारा किया गया था और उपयोगकर्ताओं द्वारा संशोधित नहीं किया जा सकता है।

आप अजगर का उपयोग कर रहे हैं, तो आप निम्न कर सकता है:

import webapp2 

AUTHORIZED_APPS = ('my-first-app', 'my-other-app') 

class MyHandler(webapp2.RequestHandler): 
    def dispatch(self): 
     app_id = self.request.headers.get('X-Appengine-Inbound-Appid', None) 

     if app_id in AUTHORIZED_APPS: 
      super(MyHandler, self).dispatch() 
     else: 
      self.abort(403) 

कि किसी भी अनुरोध है कि इसके शीर्षक में एक एक्स-AppEngine-भीतर-AppID नहीं है के लिए एक 403 को बढ़ा देंगे।

साथ ही, urlfetch का उपयोग करके एक एप्लिकेशन से दूसरे एप्लिकेशन में अनुरोध करते समय, सुनिश्चित करें कि आप follow_redirects = गलत सेट करें या हेडर जोड़ा नहीं जाता है।

+0

कोई भी जो अधिकृत ऐप्स के ऐप आईडी को जानता है वह मैन्युअल रूप से हेडर जोड़कर उनका प्रतिरूपण नहीं कर सकता? –

+0

नहीं। "यह हेडर अन्य ऐप्स या बाहरी सेवाओं द्वारा जाली नहीं जा सकता है - यह ऐप इंजन सिस्टम द्वारा संचरित है" http://stackoverflow.com/a/7961397/789417 –

+0

उपरोक्त कोड वास्तव में काम नहीं करेगा अगर वास्तव में काम नहीं करेगा एक्स-एपेंगेन-इनबाउंड-एपिड हेडर मौजूद नहीं है। यदि हेडर मौजूद नहीं है, तो app_id कोई नहीं होगा। यह जांचना कि कोई भी टुपल में नहीं है, टाइप टाइपर उत्पन्न करेगा। आप वास्तव में क्या चाहते हैं AUTHORIZED_APPS एक सूची होने के लिए है। जांच कर रहा है कि सूची में कोई भी नहीं है, Python में करने के लिए एक वैध बात है। – timbo

1

सबसे आसान तरीका (और इस मामले में पर्याप्त अच्छा) HTTP शीर्षलेख में एक रहस्य शामिल करना होगा और इसे सेवारत पक्ष पर जांचना होगा।

+0

धन्यवाद, कि वास्तव में क्या मैं इस समय कर रहा हूँ है। मुझे आश्चर्य है कि क्या कुछ ऐप इंजन-विशिष्ट तरीके से इसे संभालने का तरीका है जो इस तथ्य को लेता है कि ऐप्स उसी खाते के अंतर्गत चलते हैं। –

2

आप ऐप इंजन की Application Identity सेवा की जांच कर सकते हैं।

+0

धन्यवाद; यह मेरी अपेक्षा से अधिक जटिल है, लेकिन यह जानना अच्छा है। –

0

डुनो अगर यह काम करेगा, लेकिन आप अपने app.yaml में अपने यूआरएल हैंडलर में "लॉगिन: व्यवस्थापक" जोड़ने का प्रयास कर सकते हैं।

यह क्रॉन/कार्य कतार नौकरियों

https://developers.google.com/appengine/docs/python/config/cron#Securing_URLs_for_Cron

2

लिए काम करता है के रूप में अन्य लोगों ने बताया है, हैडर एक्स AppEngine-भीतर-AppID बाहर भरा जा रहा पर भरोसा सबसे आसान उपाय है। मुझे हाल ही में एक ही समस्या थी, लेकिन मैं X-Appengine-Inbound-Appid का उपयोग नहीं कर सका क्योंकि URLFetch उपलब्ध नहीं था (GAE Node.js)। ओएथ के माध्यम से प्रमाणित सेवा खातों का उपयोग कर समस्या को हल करने का तरीका यहां बताया गया है।

आप एक सेवा खाते की स्थापना की जरूरत है इस तरफ: https://developers.google.com/identity/protocols/application-default-credentials

तो फिर तुम बनाने के लिए क्रेडेंशियल्स का उपयोग कर सकते हैं: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount

तो उस एप्लिकेशन में आप सेवा खाता क्रेडेंशियल प्राप्त करने की आवश्यकता होगी authClient, जिसे आप अनुरोध भेजने के लिए उपयोग कर सकते हैं। आपको अपने ऑथ क्लाइंट में ओएथ स्कोप जोड़ना होगा। उपयोग करने के लिए ज्यादातर तार्किक https://www.googleapis.com/auth/userinfo.email है। यह रिसीवर को प्रेषक के सेवा खाते का ईमेल पता प्राप्त करने में सक्षम करेगा। https://developers.google.com/identity/protocols/googlescopes

यहाँ यह में काम करते हैं (इस) बनाने के लिए कोड है Node.js:

process.env.GOOGLE_APPLICATION_CREDENTIALS = <PATH TO CREDENTIALS FILE> 

google.auth.getApplicationDefault((err, authClient) => { 
    if (err) { 
    console.log("Failed to get default credentials: ", String(err)); 
    return; 
    } 

    if (authClient.createScopedRequired && authClient.createScopedRequired()) { 
    authClient = authClient.createScoped([ 
     'https://www.googleapis.com/auth/userinfo.email' 
    ]); 
    } 

    auth_client.request({ 
    url: <RECEIVER URL>, 
    method: "GET" 
    }, (error, result, response) => { 
    // Process response 
    }); 
}); 

तो रिसीवर पक्ष पर आप ईमेल पता प्रेषक की सेवा खाते का ईमेल पते से मेल खाता सत्यापित करना होगा। जब ऐप इंजन को स्थानीय रूप से बुलाया जाता है तो ओएथ अनुरोध सही तरीके से प्रमाणीकृत नहीं होता है, इसलिए यदि आप स्थानीय रूप से परीक्षण करना चाहते हैं तो आपको अनुरोध को सत्यापित करने के लिए एक यूआरएल लाने की आवश्यकता होगी।

रिसीवर पायथन:

scope = "https://www.googleapis.com/auth/userinfo.email" 
allowed_users = set([ 
    "<SENDER SERVICE ACCOUNT EMAIL>" 
]) 
IS_DEV = os.environ["SERVER_SOFTWARE"][:3] == "Dev" 

class MyHandler(webapp2.RequestHandler): 
    def get(self, clientId): 
     user = self.get_current_user() 
     if user in allowed_users: 
      # Do whatever you wanted 

    def get_current_user(self): 
     if IS_DEV: 
      token = self.request.headers.get("Authorization")[len("Bearer "):] 
      response = urlfetch.fetch(
       "https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=%s" % token 
      ) 
      return json.loads(response.content)["email"] 
     else: 
      return oauth.get_current_user(scope)