मैं जीसीपी पर्यावरण के बाहर से पायथन के माध्यम से एक आईएपी-संरक्षित ऐप इंजन मानक ऐप को प्रोग्रामेटिक रूप से एक्सेस करने का प्रयास कर रहा हूं। मैंने यहां डॉक्स में दिखाई गई विधि सहित विभिन्न विधियों का प्रयास किया है: https://cloud.google.com/iap/docs/authentication-howto#iap-make-request-python। यहाँ मेरा कोड है:
from google.auth.transport.requests import Request
from google.oauth2 import id_token
import requests
def make_iap_request(url, client_id, method='GET', **kwargs):
"""Makes a request to an application protected by Identity-Aware Proxy.
Args:
url: The Identity-Aware Proxy-protected URL to fetch.
client_id: The client ID used by Identity-Aware Proxy.
method: The request method to use
('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE')
**kwargs: Any of the parameters defined for the request function:
https://github.com/requests/requests/blob/master/requests/api.py
If no timeout is provided, it is set to 90 by default.
Returns:
The page body, or raises an exception if the page couldn't be retrieved.
"""
# Set the default timeout, if missing
if 'timeout' not in kwargs:
kwargs['timeout'] = 90
# Obtain an OpenID Connect (OIDC) token from metadata server or using service
# account.
open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
print(f'{open_id_connect_token=}')
# Fetch the Identity-Aware Proxy-protected URL, including an
# Authorization header containing "Bearer " followed by a
# Google-issued OpenID Connect token for the service account.
resp = requests.request(
method, url,
headers={'Authorization': 'Bearer {}'.format(
open_id_connect_token)}, **kwargs)
print(f'{resp=}')
if resp.status_code == 403:
raise Exception('Service account does not have permission to '
'access the IAP-protected application.')
elif resp.status_code != 200:
raise Exception(
'Bad response from application: {!r} / {!r} / {!r}'.format(
resp.status_code, resp.headers, resp.text))
else:
return resp.text
if __name__ == '__main__':
res = make_iap_request(
'https://MYAPP.ue.r.appspot.com/',
'Client ID from IAP>App Engine app>Edit OAuth Client>Client ID'
)
print(res)
जब मैं इसे स्थानीय रूप से चलाता हूं, तो मेरे पास GOOGLE_APPLICATION_CREDENTIALS पर्यावरण चर एक स्थानीय JSON क्रेडेंशियल फ़ाइल पर सेट होता है जिसमें उस सेवा खाते की कुंजी होती है जिसका मैं उपयोग करना चाहता हूं। मैंने इसे क्लाउड फ़ंक्शंस में चलाने का भी प्रयास किया है, इसलिए यह संभावित रूप से ऐप इंजन डिफ़ॉल्ट सेवा खाता (मुझे लगता है?) लेने के लिए मेटाडेटा सेवा का उपयोग करेगा।
दोनों ही मामलों में, मैं एक टोकन उत्पन्न करने में सक्षम हूं जो मान्य प्रतीत होता है। jwt.io का उपयोग करके, मैं देखता हूं कि इसमें अपेक्षित डेटा है और हस्ताक्षर मान्य है। हालांकि, जब मैं टोकन का उपयोग करके ऐप से अनुरोध करता हूं, तो मुझे हमेशा यह अपवाद मिलता है:
आवेदन से खराब प्रतिक्रिया: 401 / {'एक्स-गूग-आईएपी-जेनरेटेड-प्रतिक्रिया': 'सत्य', 'दिनांक': 'मंगल, 09 फरवरी 2021 19:25:43 जीएमटी', 'सामग्री-प्रकार': 'पाठ /html', 'सर्वर': 'Google फ़्रंटएंड', 'सामग्री-लंबाई': '47', 'Alt-Svc': 'h3-29=":443"; मा=२५९२०००,एच३-टी०५१=":४४३"; मा=२५९२०००,एच३-क्यू०५०=":४४३"; मा=२५९२०००,एच३-क्यू०४६=":४४३"; मा=२५९२०००,एच३-क्यू०४३=":४४३"; मा = २५९२०००, क्विक =": ४४३"; मा = २५९२०००; v="46,43"'} / 'अमान्य जीसीआईपी आईडी टोकन: जेडब्ल्यूटी हस्ताक्षर अमान्य है'
मुझ से ऐसी कौनसी गलती हो जाएगी?
1 उत्तर
इस समस्या का समाधान एक पहचान प्लेटफार्म पहचान टोकन के लिए Google पहचान टोकन का आदान-प्रदान करना है।
त्रुटि का कारण Invalid GCIP ID token: JWT signature is invalid
एक Google पहचान टोकन का उपयोग करने के कारण होता है जिस पर Google RSA निजी कुंजी द्वारा हस्ताक्षरित किया जाता है, न कि Google पहचान प्लेटफ़ॉर्म RSA निजी कुंजी द्वारा। मैंने त्रुटि संदेश में GCIP
को नज़रअंदाज़ कर दिया, जो एक बार यह पुष्टि करने के बाद कि उपयोग में टोकन दूषित नहीं था, मुझे समाधान बता देता।
प्रश्न में, कोड की यह पंक्ति Google पहचान टोकन प्राप्त करती है:
open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
कोड की उपरोक्त पंक्ति के लिए आवश्यक है कि Google क्लाउड एप्लिकेशन डिफ़ॉल्ट क्रेडेंशियल सेटअप हो। उदाहरण: set GOOGLE_APPLICATION_CREDENTIALS=c:\config\service-account.json
अगला कदम इस टोकन को पहचान प्लेटफॉर्म टोकन के लिए एक्सचेंज करना है:
def exchange_google_id_token_for_gcip_id_token(google_open_id_connect_token):
SIGN_IN_WITH_IDP_API = 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp'
API_KEY = '';
url = SIGN_IN_WITH_IDP_API + '?key=' + API_KEY;
data={
'requestUri': 'http://localhost',
'returnSecureToken': True,
'postBody':'id_token=' + google_open_id_connect_token + '&providerId=google.com'}
try:
resp = requests.post(url, data)
res = resp.json()
if 'error' in res:
print("Error: {}".format(res['error']['message']))
exit(1)
# print(res)
return res['idToken']
except Exception as ex:
print("Exception: {}".format(ex))
exit(1)
API कुंजी Google क्लाउड कंसोल -> आइडेंटिटी प्लेटफ़ॉर्म में पाई जा सकती है। ऊपर दाईं ओर "एप्लिकेशन सेटअप विवरण"। यह apiKey
और authDomain
दिखाएगा।
अधिक जानकारी इस लिंक पर मिल सकती है:
किसी पहचान प्लेटफ़ॉर्म टोकन के लिए Google टोकन का आदान-प्रदान करना
संबंधित सवाल
नए सवाल
google-app-engine
Google अनुप्रयोग इंजन Google-प्रबंधित डेटा केंद्रों में वेब एप्लिकेशन होस्ट करने के लिए क्लाउड कंप्यूटिंग तकनीक है। Google ऐप इंजन अपने मानक वातावरण में जावा, पायथन, गो, नोड.जेएस और पीएचपी के लिए एक सेवा (पा) के रूप में एक मंच है। इसके लचीले वातावरण में कुछ अन्य भाषाओं के साथ-साथ डॉकटर-आधारित कस्टम रनटाइम्स का भी समर्थन किया जाता है।
Authorization: Bearer <TOKEN>
में एक पहचान टोकन की आवश्यकता है। त्रुटिJWT signature is invalid
का मतलब है कि आपको शायद यह त्रुटि हो रही है कि आप अपने API/REST कॉल में टोकन का उपयोग कैसे कर रहे हैं।print(f'{open_id_connect_token=}')
? मुझे लगता है कि आप स्ट्रिंगClient ID from IAP>App Engine app>Edit OAuth Client>Client ID
को पहचान टोकन में जोड़ रहे हैं। अगर सही है, तोkwargs
कोheaders={'Authorization': 'Bearer {}'.format(open_id_connect_token)}, **kwargs)
से हटा दें