App Identity API für Python

Mit der App Identity API können Anwendungen ihre Anwendungs-ID (auch als Projekt-ID bezeichnet) ermitteln. Mithilfe der ID können App Engine-Anwendungen ihre Identität gegenüber anderen App Engine-Anwendungen, Google APIs sowie Anwendungen und Diensten von Drittanbietern bestätigen. Die Anwendungs-ID kann auch zum Generieren einer URL oder E-Mail-Adresse oder zum Ausführen einer Laufzeitentscheidung herangezogen werden.

Projekt-ID abrufen

Die Projekt-ID kann mit der Methode app_identity.get_application_id() ermittelt werden. Die WSGI- oder CGI-Umgebung stellt einige Implementierungsdetails bereit, die von der API verarbeitet werden.

Hostname der Anwendung abrufen

Standardmäßig werden App Engine-Anwendungen über URLs im Format http://<your_app_id>.appspot.com bereitgestellt, wobei die Anwendungs-ID Teil des Hostnamens ist. Wenn eine Anwendung von einer benutzerdefinierten Domain bereitgestellt wird, muss möglicherweise die gesamte Komponente des Hostnamens abgerufen werden. Verwenden Sie hierzu die Methode app_identity.get_default_version_hostname().

Identität gegenüber anderen App Engine-Anwendungen bestätigen

Wenn Sie die Identität der App Engine-Anwendung ermitteln möchten, die eine Anfrage an Ihre App Engine-Anwendung sendet, verwenden Sie den Anfrageheader X-Appengine-Inbound-Appid. Dieser Header wird der Anfrage vom URLFetch-Dienst hinzugefügt und kann vom Nutzer nicht geändert werden. Daher wird die ID der Anwendung, die die Anfrage ausführt (falls vorhanden), sicher angezeigt.

Anforderungen:

  • Nur Aufrufe an die Domain appspot.com Ihrer Anwendung enthalten den Header X-Appengine-Inbound-Appid. Aufrufe an benutzerdefinierte Domains enthalten den Header nicht.
  • Ihre Anfragen müssen so eingerichtet sein, dass sie keinen Weiterleitungen folgen. Setzen Sie den Parameter urlfetch.fetch() follow_redirects auf False.

Die eingehende ID können Sie in Ihrem Anwendungshandler überprüfen. Vergleichen Sie dazu den Inhalt des Headers X-Appengine-Inbound-Appid mit der Liste der IDs, die Anfragen senden dürfen. Beispiel:

import webapp2

class MainPage(webapp2.RequestHandler):
    allowed_app_ids = [
        'other-app-id',
        'other-app-id-2'
    ]

    def get(self):
        incoming_app_id = self.request.headers.get(
            'X-Appengine-Inbound-Appid', None)

        if incoming_app_id not in self.allowed_app_ids:
            self.abort(403)

        self.response.write('This is a protected page.')

app = webapp2.WSGIApplication([
    ('/', MainPage)
], debug=True)

Identität gegenüber Google APIs bestätigen

Google APIs verwenden zur Authentifizierung und Autorisierung das OAuth 2.0-Protokoll. Die App Identity API kann OAuth-Tokens erstellen, mit denen bestätigt werden kann, dass die Quelle einer Anfrage die Anwendung selbst ist. Die Methode get_access_token() gibt ein Zugriffstoken für einen Bereich oder eine Liste von Bereichen zurück. Dieses Token kann dann in den HTTP-Headern eines Aufrufs festgelegt werden, um die aufrufende Anwendung zu identifizieren.

Das folgende Beispiel zeigt, wie mit der App Identity API eine Authentifizierung bei der Cloud Storage API durchgeführt wird und sämtliche Buckets im Projekt abgerufen und aufgelistet werden.
import json
import logging

from google.appengine.api import app_identity
from google.appengine.api import urlfetch
import webapp2

class MainPage(webapp2.RequestHandler):
    def get(self):
        auth_token, _ = app_identity.get_access_token(
            'https://www.googleapis.com/auth/cloud-platform')
        logging.info(
            'Using token {} to represent identity {}'.format(
                auth_token, app_identity.get_service_account_name()))

        response = urlfetch.fetch(
            'https://www.googleapis.com/storage/v1/b?project={}'.format(
                app_identity.get_application_id()),
            method=urlfetch.GET,
            headers={
                'Authorization': 'Bearer {}'.format(auth_token)
            }
        )

        if response.status_code != 200:
            raise Exception(
                'Call failed. Status code {}. Body {}'.format(
                    response.status_code, response.content))

        result = json.loads(response.content)
        self.response.headers['Content-Type'] = 'application/json'
        self.response.write(json.dumps(result, indent=2))

app = webapp2.WSGIApplication([
    ('/', MainPage)
], debug=True)

Beachten Sie, dass die Identität der Anwendung durch den Dienstkontonamen dargestellt wird, der normalerweise applicationid@appspot.gserviceaccount.com lautet. Sie können den genauen Wert ermitteln, indem Sie die Methode get_service_account_name() verwenden. Bei Diensten, die ACLs anbieten, können Sie der Anwendung den Zugriff über dieses Konto gewähren.

Identität gegenüber Diensten von Drittanbietern bestätigen

Das von get_access_token() generierte Token funktioniert nur in Verbindung mit Google-Diensten. Sie können jedoch die zugrunde liegende Signaturtechnologie verwenden, um die Identität Ihrer Anwendung gegenüber anderen Diensten zu bestätigen. Die Methode sign_blob() signiert Byte mit einem privaten Schlüssel, der für Ihre Anwendung eindeutig ist. Die Methode get_public_certificates() gibt Zertifikate zurück, die zur Validierung der Signatur verwendet werden können.

Hier ist ein Beispiel für das Signieren eines Blobs und die anschließende Überprüfung der Signatur:

import base64

from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Util.asn1 import DerSequence
from google.appengine.api import app_identity
import webapp2

def verify_signature(data, signature, x509_certificate):
    """Verifies a signature using the given x.509 public key certificate."""

    # PyCrypto 2.6 doesn't support x.509 certificates directly, so we'll need
    # to extract the public key from it manually.
    # This code is based on https://github.com/google/oauth2client/blob/master
    # /oauth2client/_pycrypto_crypt.py
    pem_lines = x509_certificate.replace(b' ', b'').split()
    cert_der = base64.urlsafe_b64decode(b''.join(pem_lines[1:-1]))
    cert_seq = DerSequence()
    cert_seq.decode(cert_der)
    tbs_seq = DerSequence()
    tbs_seq.decode(cert_seq[0])
    public_key = RSA.importKey(tbs_seq[6])

    signer = PKCS1_v1_5.new(public_key)
    digest = SHA256.new(data)

    return signer.verify(digest, signature)

def verify_signed_by_app(data, signature):
    """Checks the signature and data against all currently valid certificates
    for the application."""
    public_certificates = app_identity.get_public_certificates()

    for cert in public_certificates:
        if verify_signature(data, signature, cert.x509_certificate_pem):
            return True

    return False

class MainPage(webapp2.RequestHandler):
    def get(self):
        message = 'Hello, world!'
        signing_key_name, signature = app_identity.sign_blob(message)
        verified = verify_signed_by_app(message, signature)

        self.response.content_type = 'text/plain'
        self.response.write('Message: {}\n'.format(message))
        self.response.write(
            'Signature: {}\n'.format(base64.b64encode(signature)))
        self.response.write('Verified: {}\n'.format(verified))

app = webapp2.WSGIApplication([
    ('/', MainPage)
], debug=True)

Name des standardmäßigen Cloud Storage-Buckets abrufen

Alle Anwendungen können einen standardmäßigen Cloud Storage-Bucket haben, dem 5 GB kostenloser Speicher und ein kostenloses Kontingent für E/A-Vorgänge zugeordnet sind. Der maximale Speicherplatz für diesen Bucket beträgt 5 GB. Dieser kann erhöht werden, wenn Sie die Abrechnung für die Anwendung aktivieren und den zusätzlichen Speicherplatz bezahlen. Der Bucket wird damit zu einem bezahlten Bucket.

Zum Abrufen des Standard-Buckets können Sie die App Identity API verwenden. Rufen Sie dazu google.appengine.api.app_identity.app_identity.get_default_gcs_bucket_name auf.

Hat Ihnen diese Seite weitergeholfen? Teilen Sie uns Ihr Feedback mit:

Feedback geben zu...

App Engine-Standardumgebung für Python 2