Nutzerkonten mit dem produktübergreifenden Kontoschutz schützen

Wenn Nutzer sich in Ihrer App über Google in ihren Konten anmelden können, können Sie die Sicherheit dieser freigegebenen Nutzerkonten verbessern, indem Sie die Benachrichtigungen zu Sicherheitsereignissen des Dienstes für den produktübergreifenden Kontoschutz überwachen und darauf reagieren.

Diese Benachrichtigungen informieren Sie über größere Änderungen an den Google-Konten Ihrer Nutzer, die häufig auch Sicherheitsaspekte für die Konten der Nutzer in Ihrer App haben können. Wenn beispielsweise das Google-Konto eines Nutzers gehackt wurde, kann dies zur Gefährdung des Nutzerkontos in Ihrer App durch die Wiederherstellung von E-Mail-Konten oder die Verwendung der Einmalanmeldung führen.

Um das Risikopotenzial solcher Ereignisse zu verringern, sendet Google Ihre Dienstobjekte, sogenannte Sicherheitsereignistokens. Diese Tokens enthalten nur sehr wenige Informationen – nur die Art des Sicherheitsereignisses und den Zeitpunkt des Auftretens sowie die ID des betroffenen Nutzers. Sie können sie jedoch verwenden, um entsprechende Maßnahmen zu ergreifen. Wenn beispielsweise das Google-Konto eines Nutzers manipuliert wurde, kannst du „Über Google anmelden“ für diesen Nutzer vorübergehend deaktivieren und verhindern, dass E-Mails zur Kontowiederherstellung an die Gmail-Adresse des Nutzers gesendet werden.

Der produktübergreifende Kontoschutz basiert auf dem RISC-Standard, der von der OpenID Foundation entwickelt wurde.

Überblick

Wenn Sie den produktübergreifenden Kontoschutz für Ihre Anwendung oder Ihren Dienst verwenden möchten, müssen Sie die folgenden Aufgaben ausführen:

  1. Richten Sie Ihr Projekt in der API Consoleein.

  2. Erstellen Sie einen Endpunkt für Ereignisempfänger, an den Google Tokens für Sicherheitsereignisse sendet. Dieser Endpunkt ist dafür verantwortlich, die empfangenen Tokens zu validieren und dann auf Sicherheitsereignisse in einer beliebigen Weise zu reagieren.

  3. Registrieren Sie Ihren Endpunkt bei Google, um Tokens für Sicherheitsereignisse zu erhalten.

Vorbereitung

Sie erhalten nur Sicherheitsereignistokens für Google-Nutzer, die Ihrem Dienst die Berechtigung zum Zugriff auf ihre Profilinformationen oder E-Mail-Adressen erteilt haben. Sie erhalten diese Berechtigung, indem Sie den Bereich profile oder email anfordern. Die neueren SDKs für Über Google anmelden oder Google Log-in fordern diese Bereiche standardmäßig an. Wenn Sie jedoch nicht die Standardeinstellungen verwenden oder direkt auf den OpenID Connect-Endpunkt von Google zugreifen, müssen Sie mindestens einen dieser Bereiche anfordern.

Richten Sie ein Projekt in der API Consoleein

Bevor Sie Sicherheitsereignistokens empfangen können, müssen Sie ein Dienstkonto erstellen und die RISC API im ProjektAPI Console aktivieren. Sie müssen dasselbeAPI Console -Projekt verwenden, mit dem Sie in Ihrer App auf Google-Dienste wie Google Log-in zugreifen.

So erstellen Sie das Dienstkonto:

  1. Öffnen Sie API Console Credentials page. Wenn Sie dazu aufgefordert werden, wählen Sie das ProjektAPI Consoleaus, mit dem Sie in Ihrer Anwendung auf Google-Dienste zugreifen.

  2. Klicken Sie auf Anmeldedaten erstellen > Dienstkonto.

  3. Erstellen Sie ein neues Dienstkonto mit der Rolle „RISC Configuration Admin“ (roles/riscconfigs.admin). Folgen Sie dazu dieser Anleitung.

  4. Erstellen Sie einen Schlüssel für das neu erstellte Dienstkonto. Wählen Sie den JSON-Schlüsseltyp aus und klicken Sie dann auf Erstellen. Beim Erstellen des Schlüssels laden Sie eine JSON-Datei mit den Anmeldedaten Ihres Dienstkontos herunter. Bewahren Sie diese Datei an einem sicheren Ort auf, aber auch für den Endpunkt des Ereignisempfängers zugänglich.

Notieren Sie sich auf der Seite „Anmeldedaten“ Ihres Projekts die Client-IDs, die Sie für „Über Google anmelden“ oder „Google Log-in“ (alt) verwenden. Normalerweise haben Sie eine Client-ID für jede unterstützte Plattform. Sie benötigen diese Client-IDs, um Tokens für Sicherheitsereignisse zu validieren, wie im nächsten Abschnitt beschrieben.

So aktivieren Sie die RISC API:

  1. Öffnen Sie die RISC API-Seite imAPI Console. Achten Sie darauf, dass das Projekt, mit dem Sie auf Google-Dienste zugreifen, weiterhin ausgewählt ist.

  2. Lesen Sie die RISC-Nutzungsbedingungen und machen Sie sich mit den Anforderungen vertraut.

    Wenn Sie die API für ein Projekt aktivieren, das einer Organisation gehört, müssen Sie berechtigt sein, Ihre Organisation an die RISC-Bedingungen zu binden.

  3. Klicken Sie nur auf Aktivieren, wenn Sie den RISC-Nutzungsbedingungen zustimmen.

Endpunkt für Ereignisempfänger erstellen

Wenn Sie Benachrichtigungen zu Sicherheitsereignissen von Google erhalten möchten, erstellen Sie einen HTTPS-Endpunkt, der HTTPS-POST-Anfragen verarbeitet. Nachdem Sie diesen Endpunkt registriert haben (siehe unten), beginnt Google damit, kryptografisch signierte Strings, sogenannte Sicherheitsereignis-Tokens, an den Endpunkt zu senden. Tokens für Sicherheitsereignisse sind signierte JWTs, die Informationen zu einem einzelnen sicherheitsbezogenen Ereignis enthalten.

Validieren und decodieren Sie jedes Sicherheitsereignistoken, das Sie an Ihrem Endpunkt erhalten, und gehen Sie dann entsprechend für Ihren Dienst vor. Es ist unerlässlich, das Ereignistoken vor der Decodierung zu validieren, um böswillige Angriffe durch böswillige Akteure zu verhindern. In den folgenden Abschnitten werden diese Aufgaben beschrieben:

1. Sicherheitsereignistoken decodieren und validieren

Da Sicherheitsereignistokens eine bestimmte Art von JWT sind, können Sie sie mit einer beliebigen JWT-Bibliothek decodieren und validieren, z. B. eine auf jwt.io aufgeführte. Unabhängig von der verwendeten Bibliothek muss Ihr Token-Validierungscode folgende Voraussetzungen erfüllen:

  1. Rufen Sie die Ausstellerkennung für den produktübergreifenden Kontoschutz (issuer) und den URI des Signaturschlüsselzertifikats (jwks_uri) aus dem RISC-Konfigurationsdokument von Google ab. Sie finden sie unter https://accounts.google.com/.well-known/risc-configuration.
  2. Rufe mithilfe der JWT-Bibliothek deiner Wahl die Signaturschlüssel-ID aus dem Header des Sicherheitsereignistokens ab.
  3. Rufen Sie den öffentlichen Schlüssel aus dem Dokument des Signaturschlüsselzertifikats von Google mit der Schlüssel-ID ab, die Sie im vorherigen Schritt erhalten haben. Wenn das Dokument keinen Schlüssel mit der gesuchten ID enthält, ist das Sicherheitsereignis-Token wahrscheinlich ungültig und der Endpunkt sollte den HTTP-Fehler 400 zurückgeben.
  4. Überprüfe mithilfe der JWT-Bibliothek deiner Wahl Folgendes:
    • Das Sicherheitsereignis-Token wird mit dem öffentlichen Schlüssel signiert, den Sie im vorherigen Schritt erhalten haben.
    • Die aud-Anforderung des Tokens ist eine der Client-IDs Ihrer App.
    • Die iss-Anforderung des Tokens stimmt mit der Ausstellerkennung überein, die Sie aus dem RISC-Discovery-Dokument erhalten haben. Sie müssen den Ablauf des Tokens (exp) nicht überprüfen, da Sicherheitsereignistokens historische Ereignisse darstellen und daher nicht ablaufen.

Beispiel:

Java

Mit java-jwt und jwks-rsa-java:

public DecodedJWT validateSecurityEventToken(String token) {
    DecodedJWT jwt = null;
    try {
        // In a real implementation, get these values from
        // https://accounts.google.com/.well-known/risc-configuration
        String issuer = "accounts.google.com";
        String jwksUri = "https://www.googleapis.com/oauth2/v3/certs";

        // Get the ID of the key used to sign the token.
        DecodedJWT unverifiedJwt = JWT.decode(token);
        String keyId = unverifiedJwt.getKeyId();

        // Get the public key from Google.
        JwkProvider googleCerts = new UrlJwkProvider(new URL(jwksUri), null, null);
        PublicKey publicKey = googleCerts.get(keyId).getPublicKey();

        // Verify and decode the token.
        Algorithm rsa = Algorithm.RSA256((RSAPublicKey) publicKey, null);
        JWTVerifier verifier = JWT.require(rsa)
                .withIssuer(issuer)
                // Get your apps' client IDs from the API console:
                // https://console.developers.google.com/apis/credentials?project=_
                .withAudience("123456789-abcedfgh.apps.googleusercontent.com",
                              "123456789-ijklmnop.apps.googleusercontent.com",
                              "123456789-qrstuvwx.apps.googleusercontent.com")
                .acceptLeeway(Long.MAX_VALUE)  // Don't check for expiration.
                .build();
        jwt = verifier.verify(token);
    } catch (JwkException e) {
        // Key not found. Return HTTP 400.
    } catch (InvalidClaimException e) {

    } catch (JWTDecodeException exception) {
        // Malformed token. Return HTTP 400.
    } catch (MalformedURLException e) {
        // Invalid JWKS URI.
    }
    return jwt;
}

Python

import json
import jwt       # pip install pyjwt
import requests  # pip install requests

def validate_security_token(token, client_ids):
    # Get Google's RISC configuration.
    risc_config_uri = 'https://accounts.google.com/.well-known/risc-configuration'
    risc_config = requests.get(risc_config_uri).json()

    # Get the public key used to sign the token.
    google_certs = requests.get(risc_config['jwks_uri']).json()
    jwt_header = jwt.get_unverified_header(token)
    key_id = jwt_header['kid']
    public_key = None
    for key in google_certs['keys']:
        if key['kid'] == key_id:
            public_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(key))
    if not public_key:
        raise Exception('Public key certificate not found.')
        # In this situation, return HTTP 400

    # Decode the token, validating its signature, audience, and issuer.
    try:
        token_data = jwt.decode(token, public_key, algorithms='RS256',
                                options={'verify_exp': False},
                                audience=client_ids, issuer=risc_config['issuer'])
    except:
        raise
        # Validation failed. Return HTTP 400.
    return token_data

# Get your apps' client IDs from the API console:
# https://console.developers.google.com/apis/credentials?project=_
client_ids = ['123456789-abcedfgh.apps.googleusercontent.com',
              '123456789-ijklmnop.apps.googleusercontent.com',
              '123456789-qrstuvwx.apps.googleusercontent.com']
token_data = validate_security_token(token, client_ids)

Wenn das Token gültig ist und decodiert wurde, wird der HTTP-Status 202 zurückgegeben. Bearbeiten Sie dann das Sicherheitsereignis, das im Token angezeigt wird.

2. Auf Sicherheitsereignisse reagieren

Nach der Decodierung sieht ein Sicherheitsereignistoken so aus:

{
  "iss": "https://accounts.google.com/",
  "aud": "123456789-abcedfgh.apps.googleusercontent.com",
  "iat": 1508184845,
  "jti": "756E69717565206964656E746966696572",
  "events": {
    "https://schemas.openid.net/secevent/risc/event-type/account-disabled": {
      "subject": {
        "subject_type": "iss-sub",
        "iss": "https://accounts.google.com/",
        "sub": "7375626A656374"
      },
      "reason": "hijacking"
    }
  }
}

Die Anforderungen iss und aud geben den Aussteller des Tokens (Google) und den beabsichtigten Empfänger des Tokens (Ihr Dienst) an. Sie haben diese Behauptungen im vorherigen Schritt überprüft.

Die jti-Anforderung ist ein String, der ein einzelnes Sicherheitsereignis identifiziert und für den Stream eindeutig ist. Mit dieser ID können Sie verfolgen, welche Sicherheitsereignisse Sie erhalten haben.

Die Anforderung events enthält Informationen zu dem Sicherheitsereignis, das das Token darstellt. Diese Anforderung ist eine Zuordnung von einer Ereignistyp-ID zu einer subject-Anforderung, in der der Nutzer, auf den sich das Ereignis bezieht, und allen zusätzlichen Details des Ereignisses angegeben wird, die möglicherweise verfügbar sind.

Die subject-Anforderung identifiziert einen bestimmten Nutzer anhand der eindeutigen Google-Konto-ID des Nutzers (sub). Diese Google-Konto-ID ist dieselbe Kennung (sub), die in den JWT-ID-Tokens enthalten ist, die von der neueren Bibliothek „Über Google anmelden“ (JavaScript, HTML), der alten Google Log-in-Bibliothek oder OpenID Connect ausgestellt wurden. Wenn der subject_type der Anforderung id_token_claims ist, kann sie auch das Feld email mit der E-Mail-Adresse des Nutzers enthalten.

Verwenden Sie die Informationen in der events-Anforderung, um eine geeignete Aktion für den Ereignistyp im Konto des angegebenen Nutzers auszuführen.

OAuth-Token-IDs

Bei OAuth-Ereignissen zu einzelnen Tokens enthält der Bezeichner des Token-Betreffs die folgenden Felder:

  • token_type: Nur refresh_token wird unterstützt.

  • token_identifier_alg: Mögliche Werte siehe folgende Tabelle.

  • token: siehe Tabelle unten.

token_identifier_alg Token
prefix Die ersten 16 Zeichen des Tokens.
hash_base64_sha512_sha512 Doppelter Hash des Tokens mit SHA-512.

Bei der Einbindung dieser Ereignisse wird empfohlen, die Tokens anhand dieser möglichen Werte zu indexieren, um eine schnelle Übereinstimmung beim Empfang des Ereignisses zu gewährleisten.

Unterstützte Ereignistypen

Der produktübergreifende Kontoschutz unterstützt die folgenden Arten von Sicherheitsereignissen:

Ereignistyp Attributes Reagieren
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked Erforderlich: Schützen Sie das Konto des Nutzers noch einmal, indem Sie die derzeit geöffneten Sitzungen beenden.
https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked

Erforderlich: Wenn das Token für Google Log-in vorgesehen ist, werden die derzeit geöffneten Sitzungen beendet. Außerdem kannst du dem Nutzer vorschlagen, eine alternative Anmeldemethode einzurichten.

Empfohlen: Wenn das Token für den Zugriff auf andere Google APIs bestimmt ist, lösche alle gespeicherten OAuth-Tokens des Nutzers.

https://schemas.openid.net/secevent/oauth/event-type/token-revoked Informationen zu Token-IDs finden Sie im Abschnitt OAuth-Token-IDs.

Erforderlich: Wenn Sie das entsprechende Aktualisierungstoken speichern, löschen Sie es und bitten Sie den Nutzer um seine erneute Einwilligung, sobald ein Zugriffstoken benötigt wird.

https://schemas.openid.net/secevent/risc/event-type/account-disabled reason=hijacking,
reason=bulk-account

Erforderlich: Wenn der Grund für die Deaktivierung des Kontos hijacking war, schützen Sie das Konto des Nutzers noch einmal, indem Sie die derzeit geöffneten Sitzungen beenden.

Empfohlen: Wenn der Grund für die Deaktivierung des Kontos bulk-account war, analysieren Sie die Aktivitäten des Nutzers in Ihrem Dienst und legen Sie geeignete Folgemaßnahmen fest.

Empfohlen: Wenn kein Grund angegeben wurde, deaktivieren Sie Google Log-in für den Nutzer und deaktivieren Sie die Kontowiederherstellung über die E-Mail-Adresse, die mit dem Google-Konto des Nutzers verknüpft ist (normalerweise, aber nicht unbedingt ein Gmail-Konto). Bieten Sie dem Nutzer eine alternative Anmeldemethode an.

https://schemas.openid.net/secevent/risc/event-type/account-enabled Empfohlen: Aktivieren Sie Google Log-in für den Nutzer wieder und die Kontowiederherstellung mit der E-Mail-Adresse des Google-Kontos des Nutzers.
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required Empfohlen: Achten Sie auf verdächtige Aktivitäten in Ihrem Dienst und ergreifen Sie entsprechende Maßnahmen.
https://schemas.openid.net/secevent/risc/event-type/verification state=state Empfohlen: Protokollieren Sie, dass ein Testtoken empfangen wurde.

Duplizierte und verpasste Termine

Beim produktübergreifenden Kontoschutz wird versucht, Ereignisse noch einmal auszuliefern, bei denen davon auszugehen ist, dass sie nicht ausgeliefert wurden. Daher kann es vorkommen, dass Sie dasselbe Ereignis mehrmals erhalten. Wenn das zu wiederholten Aktionen führen könnte, die für Nutzer ungünstig sind, können Sie die jti-Anforderung verwenden, um Ereignisse zu entfernen. Dabei handelt es sich um eine eindeutige Kennung für ein Ereignis. Es gibt externe Tools wie Google Cloud Dataflow, die Ihnen beim Ausführen des Deduplizierens von Dataflow helfen können.

Ereignisse werden mit begrenzten Wiederholungsversuchen zugestellt. Wenn der Empfänger also über einen längeren Zeitraum nicht erreichbar ist, verpassen Sie möglicherweise einige Ereignisse.

Empfänger registrieren

Damit Sie Sicherheitsereignisse empfangen können, registrieren Sie den Empfängerendpunkt mit der RISC API. Für Aufrufe der RISC API muss ein Autorisierungstoken angegeben werden.

Sie erhalten nur für Nutzer Ihrer Anwendung Sicherheitsereignisse. Daher müssen Sie in Ihrem GCP-Projekt einen OAuth-Zustimmungsbildschirm konfiguriert haben. Dies ist eine Voraussetzung für die unten beschriebenen Schritte.

1. Autorisierungstoken generieren

Zum Generieren eines Autorisierungstokens für die RISC API musst du ein JWT mit den folgenden Anforderungen erstellen:

{
  "iss": SERVICE_ACCOUNT_EMAIL,
  "sub": SERVICE_ACCOUNT_EMAIL,
  "aud": "https://risc.googleapis.com/google.identity.risc.v1beta.RiscManagementService",
  "iat": CURRENT_TIME,
  "exp": CURRENT_TIME + 3600
}

Signiere das JWT mit dem privaten Schlüssel deines Dienstkontos, den du in der JSON-Datei findest, die du beim Erstellen des Dienstkontoschlüssels heruntergeladen hast.

Beispiel:

Java

Mit java-jwt und der Authentifizierungsbibliothek von Google:

public static String makeBearerToken() {
    String token = null;
    try {
        // Get signing key and client email address.
        FileInputStream is = new FileInputStream("your-service-account-credentials.json");
        ServiceAccountCredentials credentials =
               (ServiceAccountCredentials) GoogleCredentials.fromStream(is);
        PrivateKey privateKey = credentials.getPrivateKey();
        String keyId = credentials.getPrivateKeyId();
        String clientEmail = credentials.getClientEmail();

        // Token must expire in exactly one hour.
        Date issuedAt = new Date();
        Date expiresAt = new Date(issuedAt.getTime() + 3600000);

        // Create signed token.
        Algorithm rsaKey = Algorithm.RSA256(null, (RSAPrivateKey) privateKey);
        token = JWT.create()
                .withIssuer(clientEmail)
                .withSubject(clientEmail)
                .withAudience("https://risc.googleapis.com/google.identity.risc.v1beta.RiscManagementService")
                .withIssuedAt(issuedAt)
                .withExpiresAt(expiresAt)
                .withKeyId(keyId)
                .sign(rsaKey);
    } catch (ClassCastException e) {
        // Credentials file doesn't contain a service account key.
    } catch (IOException e) {
        // Credentials file couldn't be loaded.
    }
    return token;
}

Python

import json
import time

import jwt  # pip install pyjwt

def make_bearer_token(credentials_file):
    with open(credentials_file) as service_json:
        service_account = json.load(service_json)
        issuer = service_account['client_email']
        subject = service_account['client_email']
        private_key_id = service_account['private_key_id']
        private_key = service_account['private_key']
    issued_at = int(time.time())
    expires_at = issued_at + 3600
    payload = {'iss': issuer,
               'sub': subject,
               'aud': 'https://risc.googleapis.com/google.identity.risc.v1beta.RiscManagementService',
               'iat': issued_at,
               'exp': expires_at}
    encoded = jwt.encode(payload, private_key, algorithm='RS256',
                         headers={'kid': private_key_id})
    return encoded

auth_token = make_bearer_token('your-service-account-credentials.json')

Dieses Autorisierungstoken kann eine Stunde lang für RISC API-Aufrufe verwendet werden. Generieren Sie nach Ablauf des Tokens ein neues, um weiterhin RISC API-Aufrufe auszuführen.

2. RISC-Stream-Konfigurations-API aufrufen

Da Sie nun ein Autorisierungstoken haben, können Sie mit der RISC API den Stream für Sicherheitsereignisse Ihres Projekts konfigurieren und unter anderem den Empfängerendpunkt registrieren.

Senden Sie dazu eine HTTPS-POST-Anfrage an https://risc.googleapis.com/v1beta/stream:update und geben Sie dabei Ihren Empfängerendpunkt und die Arten von Sicherheitsereignissen an, die Sie interessieren:

POST /v1beta/stream:update HTTP/1.1
Host: risc.googleapis.com
Authorization: Bearer AUTH_TOKEN

{
  "delivery": {
    "delivery_method":
      "https://schemas.openid.net/secevent/risc/delivery-method/push",
    "url": RECEIVER_ENDPOINT
  },
  "events_requested": [
    SECURITY_EVENT_TYPES
  ]
}

Beispiel:

Java

public static void configureEventStream(final String receiverEndpoint,
                                        final List<String> eventsRequested,
                                        String authToken) throws IOException {
    ObjectMapper jsonMapper = new ObjectMapper();
    String streamConfig = jsonMapper.writeValueAsString(new Object() {
        public Object delivery = new Object() {
            public String delivery_method =
                    "https://schemas.openid.net/secevent/risc/delivery-method/push";
            public String url = receiverEndpoint;
        };
        public List<String> events_requested = eventsRequested;
    });

    HttpPost updateRequest = new HttpPost("https://risc.googleapis.com/v1beta/stream:update");
    updateRequest.addHeader("Content-Type", "application/json");
    updateRequest.addHeader("Authorization", "Bearer " + authToken);
    updateRequest.setEntity(new StringEntity(streamConfig));

    HttpResponse updateResponse = new DefaultHttpClient().execute(updateRequest);
    Header[] responseContentTypeHeaders = updateResponse.getHeaders("Content-Type");
    StatusLine responseStatus = updateResponse.getStatusLine();
    int statusCode = responseStatus.getStatusCode();
    HttpEntity entity = updateResponse.getEntity();
    // Now handle response
}

// ...

configureEventStream(
        "https://your-service.example.com/security-event-receiver",
        Arrays.asList(
                "https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required",
                "https://schemas.openid.net/secevent/risc/event-type/account-disabled"),
        authToken);

Python

import requests

def configure_event_stream(auth_token, receiver_endpoint, events_requested):
    stream_update_endpoint = 'https://risc.googleapis.com/v1beta/stream:update'
    headers = {'Authorization': 'Bearer {}'.format(auth_token)}
    stream_cfg = {'delivery': {'delivery_method': 'https://schemas.openid.net/secevent/risc/delivery-method/push',
                               'url': receiver_endpoint},
                  'events_requested': events_requested}
    response = requests.post(stream_update_endpoint, json=stream_cfg, headers=headers)
    response.raise_for_status()  # Raise exception for unsuccessful requests

configure_event_stream(auth_token, 'https://your-service.example.com/security-event-receiver',
                       ['https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required',
                        'https://schemas.openid.net/secevent/risc/event-type/account-disabled'])

Wenn die Anfrage HTTP 200 zurückgibt, wurde der Ereignisstream erfolgreich konfiguriert und der Empfängerendpunkt sollte Sicherheitsereignistokens empfangen. Im nächsten Abschnitt wird beschrieben, wie Sie die Streamkonfiguration und den Endpunkt testen können, um zu prüfen, ob alles ordnungsgemäß funktioniert.

Aktuelle Streamkonfiguration abrufen und aktualisieren

Wenn Sie die Streamkonfiguration in Zukunft ändern möchten, können Sie eine autorisierte GET-Anfrage an https://risc.googleapis.com/v1beta/stream senden, um die aktuelle Streamkonfiguration abzurufen, den Antworttext ändern und dann die geänderte Konfiguration wie oben beschrieben an https://risc.googleapis.com/v1beta/stream:update zurücksenden.

Ereignisstream beenden und fortsetzen

Wenn Sie den Ereignisstream von Google beenden müssen, senden Sie eine autorisierte POST-Anfrage an https://risc.googleapis.com/v1beta/stream/status:update mit { "status": "disabled" } im Anfragetext. Solange der Stream deaktiviert ist, sendet Google keine Ereignisse an Ihren Endpunkt und puffert auch keine Sicherheitsereignisse, wenn sie auftreten. Wenn Sie den Ereignisstream wieder aktivieren möchten, senden Sie { "status": "enabled" } an denselben Endpunkt.

3. Optional: Streamkonfiguration testen

Sie können prüfen, ob die Streamkonfiguration und der Empfängerendpunkt korrekt funktionieren, indem Sie ein Bestätigungstoken über den Ereignisstream senden. Dieses Token kann einen eindeutigen String enthalten, mit dem Sie prüfen können, ob das Token an Ihrem Endpunkt empfangen wurde. Wenn Sie diesen Ablauf verwenden möchten, müssen Sie den Ereignistyp https://schemas.openid.net/secevent/risc/event-type/verification registrieren abonnieren.

Wenn Sie ein Bestätigungstoken anfordern möchten, stellen Sie eine autorisierte HTTPS-POST-Anfrage an https://risc.googleapis.com/v1beta/stream:verify. Geben Sie im Text der Anfrage einen String zur Identifizierung an:

{
  "state": "ANYTHING"
}

Beispiel:

Java

public static void testEventStream(final String stateString,
                                   String authToken) throws IOException {
    ObjectMapper jsonMapper = new ObjectMapper();
    String json = jsonMapper.writeValueAsString(new Object() {
        public String state = stateString;
    });

    HttpPost updateRequest = new HttpPost("https://risc.googleapis.com/v1beta/stream:verify");
    updateRequest.addHeader("Content-Type", "application/json");
    updateRequest.addHeader("Authorization", "Bearer " + authToken);
    updateRequest.setEntity(new StringEntity(json));

    HttpResponse updateResponse = new DefaultHttpClient().execute(updateRequest);
    Header[] responseContentTypeHeaders = updateResponse.getHeaders("Content-Type");
    StatusLine responseStatus = updateResponse.getStatusLine();
    int statusCode = responseStatus.getStatusCode();
    HttpEntity entity = updateResponse.getEntity();
    // Now handle response
}

// ...

testEventStream("Test token requested at " + new Date().toString(), authToken);

Python

import requests
import time

def test_event_stream(auth_token, nonce):
    stream_verify_endpoint = 'https://risc.googleapis.com/v1beta/stream:verify'
    headers = {'Authorization': 'Bearer {}'.format(auth_token)}
    state = {'state': nonce}
    response = requests.post(stream_verify_endpoint, json=state, headers=headers)
    response.raise_for_status()  # Raise exception for unsuccessful requests

test_event_stream(auth_token, 'Test token requested at {}'.format(time.ctime()))

Wenn die Anfrage erfolgreich ist, wird das Bestätigungstoken an den registrierten Endpunkt gesendet. Wenn Ihr Endpunkt beispielsweise Überprüfungstokens verarbeitet, indem er diese einfach protokolliert, können Sie Ihre Logs überprüfen, um zu bestätigen, dass das Token empfangen wurde.

Fehlercode-Referenz

Die folgenden Fehler können von der RISC API zurückgegeben werden:

Fehlercode Fehlermeldung Vorgeschlagene Aktionen
400 Die Streamkonfiguration muss das Feld $fieldname enthalten. Ihre Anfrage an den Endpunkt https://risc.googleapis.com/v1beta/stream:update ist ungültig oder kann nicht geparst werden. Bitte geben Sie $fieldname in Ihrer Anfrage an.
401 Nicht autorisiert. Die Autorisierung ist fehlgeschlagen. Im Anhang der Anfrage muss ein Autorisierungstoken angehängt sein. Das Token muss gültig und nicht abgelaufen sein.
403 Der Endpunkt für die Zustellung muss eine HTTPS-URL sein. Der Endpunkt für die Zustellung (d.h. den Endpunkt, an den RISC-Ereignisse gesendet werden sollen) muss HTTPS sein. Wir senden keine RISC-Ereignisse an HTTP-URLs.
403 Die vorhandene Streamkonfiguration hat keine spezifikationskonforme Übermittlungsmethode für RISC. Ihr Google Cloud-Projekt muss bereits eine RISC-Konfiguration haben. Wenn Sie Firebase verwenden und Google Log-in aktiviert haben, verwaltet Firebase das RISC für Ihr Projekt. Sie können keine benutzerdefinierte Konfiguration erstellen. Wenn Sie Google Log-in nicht für Ihr Firebase-Projekt verwenden, deaktivieren Sie es und versuchen Sie nach einer Stunde noch einmal, das Update durchzuführen.
403 Das Projekt wurde nicht gefunden. Achten Sie darauf, dass Sie das richtige Dienstkonto für das richtige Projekt verwenden. Möglicherweise verwenden Sie ein Dienstkonto, das mit einem gelöschten Projekt verknüpft ist. Hier erfahren Sie, wie Sie alle mit einem Projekt verknüpften Dienstkonten aufrufen.
403 Das Dienstkonto benötigt die Berechtigung für den Zugriff auf Ihre RISC-Konfiguration Rufen Sie die API Console Ihres Projekts auf und weisen Sie dem Dienstkonto, über das die Aufrufe an Ihr Projekt erfolgen, die Rolle „RISC Configuration Admin“ (roles/riscconfigs.admin) zu. Folgen Sie dazu dieser Anleitung.
403 Stream Management APIs sollten nur von einem Dienstkonto aufgerufen werden. Hier finden Sie weitere Informationen zum Aufrufen von Google APIs mit einem Dienstkonto.
403 Der Zustellungsendpunkt gehört zu keiner Domain Ihres Projekts. Jedes Projekt verfügt über eine Reihe von autorisierten Domains. Wenn Ihr Bereitstellungsendpunkt (d.h. der Endpunkt, an den RISC-Ereignisse gesendet werden sollen) nicht auf einem dieser Dienste gehostet wird, müssen Sie diesem Satz die Domain des Endpunkts hinzufügen.
403 Damit Sie diese API verwenden können, muss für Ihr Projekt mindestens ein OAuth-Client konfiguriert sein. RISC funktioniert nur, wenn du eine App erstellst, die Google Log-in unterstützt. Für diese Verbindung ist ein OAuth-Client erforderlich. Wenn Ihr Projekt keine OAuth-Clients hat, ist RISC wahrscheinlich nicht nützlich für Sie. Weitere Informationen zur Verwendung von OAuth durch Google für unsere APIs
403

Nicht unterstützter Status.

Ungültiger Status

Aktuell werden nur die Stream-Status „enabled“ und „disabled“ unterstützt.
404

Projekt hat keine RISC-Konfiguration.

Für das Projekt ist keine RISC-Konfiguration vorhanden. Der Status kann nicht aktualisiert werden.

Rufen Sie den Endpunkt https://risc.googleapis.com/v1beta/stream:update auf, um eine neue Streamkonfiguration zu erstellen.
4XX/5XX Der Status kann nicht aktualisiert werden. Weitere Informationen finden Sie in der detaillierten Fehlermeldung.

Zugriffstoken-Bereiche

Wenn Sie Zugriffstokens für die Authentifizierung bei der RISC API verwenden möchten, muss Ihre Anwendung die folgenden Bereiche anfordern:

Endpunkt Scope (Bereich)
https://risc.googleapis.com/v1beta/stream/status https://www.googleapis.com/auth/risc.status.readonly ODER https://www.googleapis.com/auth/risc.status.readwrite
https://risc.googleapis.com/v1beta/stream/status:update https://www.googleapis.com/auth/risc.status.readwrite
https://risc.googleapis.com/v1beta/stream https://www.googleapis.com/auth/risc.configuration.readonly ODER https://www.googleapis.com/auth/risc.configuration.readwrite
https://risc.googleapis.com/v1beta/stream:update https://www.googleapis.com/auth/risc.configuration.readwrite
https://risc.googleapis.com/v1beta/stream:verify https://www.googleapis.com/auth/risc.verify

Benötigen Sie Hilfe?

Sehen Sie sich als Erstes den Abschnitt mit der Fehlercode-Referenz an. Falls Sie noch Fragen haben, können Sie diese auf Stack Overflow mit dem Tag #SecEvents posten.