Ochrona kont użytkowników za pomocą Ochrony wszystkich kont

Jeśli Twoja aplikacja umożliwia użytkownikom logowanie się na konta za pomocą Google, możesz zwiększyć bezpieczeństwo tych kont, nasłuchując powiadomień o zdarzeniach związanych z bezpieczeństwem dostarczanych przez usługę Ochrona wszystkich kont i reagując na nie.

Te powiadomienia informują o istotnych zmianach na kontach Google użytkowników, które często mogą mieć wpływ na bezpieczeństwo ich kont w Twojej aplikacji. Jeśli na przykład konto Google użytkownika zostanie przejęte, może to potencjalnie doprowadzić do przejęcia jego konta w Twojej aplikacji przez odzyskiwanie konta e-mail lub użycie logowania jednokrotnego.

Aby pomóc Ci zmniejszyć potencjalne ryzyko związane z takimi zdarzeniami, Google wysyła do Twoich usług obiekty zwane tokenami zdarzeń związanych z bezpieczeństwem. Te tokeny ujawniają bardzo mało informacji – tylko typ zdarzenia związanego z bezpieczeństwem, czas jego wystąpienia i identyfikator użytkownika, którego dotyczy. Możesz jednak używać ich do podejmowania odpowiednich działań w odpowiedzi na takie zdarzenia. Jeśli na przykład konto Google użytkownika zostanie przejęte, możesz tymczasowo wyłączyć logowanie przez Google dla tego użytkownika i zapobiec wysyłaniu e-maili z prośbą o przywrócenie konta na adres Gmail użytkownika.

Ochrona wszystkich kont opiera się na standardzie RISC opracowanym w ramach OpenID Foundation.

Przegląd

Aby korzystać z Ochrony wszystkich kont w aplikacji lub usłudze, musisz wykonać te czynności:

  1. Skonfiguruj projekt w API Console.

  2. Utwórz punkt końcowy odbiornika zdarzeń, do którego Google będzie wysyłać tokeny zdarzeń związanych z bezpieczeństwem. Ten punkt końcowy odpowiada za weryfikację otrzymywanych tokenów, a następnie za reagowanie na zdarzenia związane z bezpieczeństwem w dowolny wybrany przez Ciebie sposób.

  3. Zarejestruj punkt końcowy w Google, aby zacząć otrzymywać tokeny zdarzeń związanych z bezpieczeństwem.

Warunek wstępny

Otrzymujesz tokeny zdarzeń związanych z bezpieczeństwem tylko w przypadku użytkowników Google, którzy przyznali Twojej usłudze uprawnienia dostępu do informacji o profilu lub adresów e-mail. To uprawnienie uzyskasz, prosząc o zakresy profile lub email. Nowsze SDK Sign In With Google i starsze SDK Google Sign-in domyślnie wysyłają żądania tych zakresów, ale jeśli nie używasz ustawień domyślnych lub uzyskujesz dostęp do punktu końcowego OpenID Connect Google bezpośrednio, upewnij się, że wysyłasz żądanie co najmniej jednego z tych zakresów.

Skonfiguruj projekt w API Console

Zanim zaczniesz otrzymywać tokeny zdarzeń związanych z bezpieczeństwem, musisz utworzyć konto usługi i włączyć interfejs RISC API w API Console projekcie. W aplikacji musisz używać tego samegoAPI Console projektu, którego używasz do uzyskiwania dostępu do usług Google, takich jak logowanie przez Google.

Aby utworzyć konto usługi:

  1. Otwórz API Console Credentials page. Gdy pojawi się taka prośba, wybierzAPI Consoleprojekt, którego używasz do uzyskiwania dostępu do usług Google w aplikacji.

  2. Kliknij Utwórz dane logowania > Konto usługi.

  3. Utwórz nowe konto usługi z rolą Administrator konfiguracji RISC (roles/riscconfigs.admin), postępując zgodnie z tymi instrukcjami.

  4. Utwórz klucz dla nowo utworzonego konta usługi. Wybierz typ klucza JSON i kliknij Utwórz. Po utworzeniu klucza pobierzesz plik JSON zawierający dane logowania konta usługi. Przechowuj ten plik w bezpiecznym, ale dostępnym miejscu dla punktu końcowego odbiorcy zdarzeń.

Na stronie Dane logowania projektu zanotuj też identyfikatory klienta, których używasz w przypadku funkcji Zaloguj się przez Google lub Logowanie przez Google (starsza wersja). Zwykle masz identyfikator klienta dla każdej obsługiwanej platformy. Te identyfikatory klientów będą potrzebne do weryfikacji tokenów zdarzeń związanych z bezpieczeństwem, co opisujemy w następnej sekcji.

Aby włączyć interfejs RISC API:

  1. Otwórz stronę interfejsu RISC API w API Console. Sprawdź, czy projekt, którego używasz do uzyskiwania dostępu do usług Google, jest nadal wybrany.

  2. Przeczytaj Warunki RISC i upewnij się, że rozumiesz wymagania.

    Jeśli włączasz interfejs API w projekcie należącym do organizacji, upewnij się, że masz uprawnienia do powiązania organizacji z Warunkami RISC.

  3. Kliknij Włącz tylko wtedy, gdy zgadzasz się na Warunki RISC.

Tworzenie punktu końcowego odbiorcy zdarzeń

Aby otrzymywać od Google powiadomienia o zdarzeniach związanych z bezpieczeństwem, utwórz punkt końcowy HTTPS, który obsługuje żądania HTTPS POST. Po zarejestrowaniu tego punktu końcowego (patrz poniżej) Google zacznie wysyłać do niego ciągi znaków podpisane kryptograficznie, zwane tokenami zdarzeń związanych z bezpieczeństwem. Tokeny zdarzeń związanych z bezpieczeństwem to podpisane tokeny JWT, które zawierają informacje o pojedynczym zdarzeniu związanym z bezpieczeństwem.

Każdy token zdarzenia związanego z bezpieczeństwem otrzymany w punkcie końcowym najpierw zweryfikuj i zdekoduj, a potem obsłuż zdarzenie związane z bezpieczeństwem w sposób odpowiedni dla Twojej usługi. Konieczne jest sprawdzenie tokena zdarzenia przed jego dekodowaniem, aby zapobiec złośliwym atakom ze strony nieuczciwych podmiotów. Te zadania są opisane w sekcjach poniżej:

1. Dekodowanie i weryfikowanie tokena zdarzenia związanego z zabezpieczeniami

Tokeny zdarzeń związanych z bezpieczeństwem to szczególny rodzaj tokenów JWT, więc do ich dekodowania i weryfikowania możesz używać dowolnej biblioteki JWT, np. wymienionej na stronie jwt.io. Niezależnie od tego, której biblioteki używasz, kod weryfikacji tokena musi wykonywać te czynności:

  1. Pobierz identyfikator wydawcy ochrony między kontami (issuer) i identyfikator URI certyfikatu klucza podpisywania (jwks_uri) z dokumentu konfiguracji RISC Google, który znajdziesz pod adresem https://accounts.google.com/.well-known/risc-configuration.
  2. Korzystając z wybranej biblioteki JWT, pobierz identyfikator klucza podpisywania z nagłówka tokena zdarzenia związanego z bezpieczeństwem.
  3. Z dokumentu certyfikatu klucza podpisywania Google pobierz klucz publiczny z identyfikatorem klucza uzyskanym w poprzednim kroku. Jeśli dokument nie zawiera klucza z szukanym identyfikatorem, prawdopodobnie token zdarzenia związanego z bezpieczeństwem jest nieprawidłowy, a punkt końcowy powinien zwrócić błąd HTTP 400.
  4. Za pomocą wybranej biblioteki JWT sprawdź te elementy:
    • Token zdarzenia związanego z bezpieczeństwem jest podpisany kluczem publicznym uzyskanym w poprzednim kroku.
    • Roszczenie aud tokena jest jednym z identyfikatorów klienta Twojej aplikacji.
    • Deklaracja iss w tokenie jest zgodna z identyfikatorem wydawcy uzyskanym z dokumentu wykrywania RISC. Pamiętaj, że nie musisz weryfikować wygaśnięcia tokena (exp), ponieważ tokeny zdarzeń związanych z bezpieczeństwem reprezentują zdarzenia historyczne i nie wygasają.

Na przykład:

Java

Korzystanie z bibliotek java-jwtjwks-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)

Jeśli token jest prawidłowy i został prawidłowo zdekodowany, zwróć stan HTTP 202. Następnie obsłuż zdarzenie związane z bezpieczeństwem wskazane przez token.

2. Obsługa zdarzeń związanych z bezpieczeństwem

Po zdekodowaniu token zdarzenia związanego z bezpieczeństwem wygląda tak jak w tym przykładzie:

{
  "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"
    }
  }
}

Roszczenia issaud wskazują wystawcę tokena (Google) i jego docelowego odbiorcę (Twoją usługę). Te roszczenia zostały zweryfikowane w poprzednim kroku.

Roszczenie jti to ciąg tekstowy, który identyfikuje pojedyncze zdarzenie związane z bezpieczeństwem i jest unikalny w ramach strumienia. Możesz używać tego identyfikatora do śledzenia otrzymanych zdarzeń związanych z bezpieczeństwem.

Roszczenie events zawiera informacje o zdarzeniu związanym z bezpieczeństwem, które reprezentuje token. To roszczenie jest mapowaniem identyfikatora typu zdarzenia na subjectroszczenie, które określa użytkownika, którego dotyczy to zdarzenie, oraz wszelkie dodatkowe szczegóły dotyczące zdarzenia, które mogą być dostępne.

Roszczenie subject identyfikuje konkretnego użytkownika za pomocą jego unikalnego identyfikatora konta Google (sub). Ten identyfikator konta Google to ten sam identyfikator (sub), który jest zawarty w tokenach tożsamości JWT wydawanych przez nowszą bibliotekę Logowania przez Google (JavaScript, HTML), starszą bibliotekę Logowania przez Google lub OpenID Connect. Gdy subject_type roszczenia ma wartość id_token_claims, może też zawierać pole email z adresem e-mail użytkownika.

Użyj informacji z deklaracji events, aby podjąć odpowiednie działania w przypadku typu zdarzenia na koncie określonego użytkownika.

Identyfikatory tokenów OAuth

W przypadku zdarzeń OAuth dotyczących poszczególnych tokenów typ identyfikatora podmiot tokena zawiera te pola:

  • token_type: obsługiwana jest tylko wartość refresh_token.

  • token_identifier_alg: możliwe wartości znajdziesz w tabeli poniżej.

  • token: patrz tabela poniżej.

token_identifier_alg token
prefix Pierwsze 16 znaków tokena.
hash_base64_sha512_sha512 Podwójny hash tokena z użyciem SHA-512.

Jeśli integrujesz się z tymi zdarzeniami, zalecamy indeksowanie tokenów na podstawie tych możliwych wartości, aby zapewnić szybkie dopasowanie po otrzymaniu zdarzenia.

Obsługiwane typy zdarzeń

Ochrona wszystkich kont obsługuje te typy zdarzeń związanych z bezpieczeństwem:

Typ zdarzenia Atrybuty Jak odpowiedzieć
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked Wymagane: ponownie zabezpiecz konto użytkownika, zamykając jego aktualnie otwarte sesje.
https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked

Wymagane: jeśli token służy do logowania w Google, zakończ otwarte sesje użytkownika. Możesz też zaproponować użytkownikowi skonfigurowanie alternatywnej metody logowania.

Sugerowane: jeśli token służy do uzyskiwania dostępu do innych interfejsów API Google, usuń wszystkie zapisane tokeny OAuth użytkownika.

https://schemas.openid.net/secevent/oauth/event-type/token-revoked Identyfikatory tokenów znajdziesz w sekcji Identyfikatory tokenów OAuth.

Wymagane: jeśli przechowujesz odpowiedni token odświeżania, usuń go i poproś użytkownika o ponowne wyrażenie zgody przy następnej potrzebie uzyskania tokena dostępu.

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

Wymagane: jeśli powodem wyłączenia konta było hijacking, ponownie zabezpiecz konto użytkownika, zamykając jego aktualnie otwarte sesje.

Sugerowane: jeśli powodem wyłączenia konta było bulk-account, przeanalizuj aktywność użytkownika w usłudze i określ odpowiednie działania, które należy podjąć.

Sugerowane: jeśli nie podano przyczyny, wyłącz logowanie przez Google dla użytkownika i wyłącz odzyskiwanie konta za pomocą adresu e-mail powiązanego z kontem Google użytkownika (zwykle, ale niekoniecznie, jest to konto Gmail). Zaoferuj użytkownikowi alternatywną metodę logowania.

https://schemas.openid.net/secevent/risc/event-type/account-enabled Sugerowane działanie: ponownie włącz logowanie przez Google dla użytkownika i ponownie włącz odzyskiwanie konta za pomocą adresu e-mail konta Google użytkownika.
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required Sugerowane: zwracaj uwagę na podejrzaną aktywność w usłudze i podejmuj odpowiednie działania.
https://schemas.openid.net/secevent/risc/event-type/verification state=state Sugerowane: rejestrowanie otrzymania tokena testowego.

Zduplikowane i pominięte zdarzenia

Ochrona wszystkich kont spróbuje ponownie dostarczyć zdarzenia, które jej zdaniem nie zostały dostarczone. Dlatego to samo zdarzenie może czasami docierać do Ciebie wielokrotnie. Jeśli może to powodować powtarzające się działania, które utrudniają korzystanie z usługi, rozważ użycie roszczenia jti (które jest niepowtarzalnym identyfikatorem zdarzenia) do usunięcia duplikatów zdarzeń. Istnieją zewnętrzne narzędzia, takie jak Google Cloud Dataflow, które mogą Ci pomóc w wykonaniu przepływu danych usuwającego duplikaty.

Pamiętaj, że wydarzenia są dostarczane z ograniczoną liczbą ponownych prób, więc jeśli odbiornik jest wyłączony przez dłuższy czas, możesz na stałe utracić niektóre wydarzenia.

Rejestrowanie odbiornika

Aby zacząć otrzymywać zdarzenia związane z bezpieczeństwem, zarejestruj punkt końcowy odbiorcy za pomocą interfejsu RISC API. Wywołania interfejsu RISC API muszą być powiązane z tokenem autoryzacji.

Zdarzenia związane z bezpieczeństwem będziesz otrzymywać tylko w przypadku użytkowników Twojej aplikacji, więc musisz mieć skonfigurowany ekran zgody OAuth w projekcie GCP jako warunek wstępny do wykonania opisanych poniżej czynności.

1. Generowanie tokena autoryzacji

Aby wygenerować token autoryzacji dla interfejsu RISC API, utwórz token JWT z tymi roszczeniami:

{
  "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
}

Podpisz token JWT za pomocą klucza prywatnego konta usługi, który znajdziesz w pliku JSON pobranym podczas tworzenia klucza konta usługi.

Na przykład:

Java

Używanie java-jwt i biblioteki uwierzytelniania 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')

Ten token autoryzacji może być używany do wywoływania interfejsu RISC API przez godzinę. Gdy token wygaśnie, wygeneruj nowy, aby nadal wywoływać interfejs RISC API.

2. Wywoływanie interfejsu RISC Stream Configuration API

Gdy uzyskasz token autoryzacji, możesz użyć interfejsu RISC API do skonfigurowania strumienia zdarzeń związanych z bezpieczeństwem w projekcie, w tym zarejestrowania punktu końcowego odbiorcy.

Aby to zrobić, wyślij żądanie HTTPS POST do https://risc.googleapis.com/v1beta/stream:update, określając punkt końcowy odbiorcy i rodzaje zdarzeń związanych z bezpieczeństwem, które Cię interesują:

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
  ]
}

Na przykład:

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'])

Jeśli żądanie zwróci kod HTTP 200, strumień zdarzeń został skonfigurowany i punkt końcowy odbiorcy powinien zacząć otrzymywać tokeny zdarzeń związanych z bezpieczeństwem. W następnej sekcji znajdziesz opis testowania konfiguracji strumienia i punktu końcowego, aby sprawdzić, czy wszystko działa prawidłowo.

Pobieranie i aktualizowanie bieżącej konfiguracji strumienia

Jeśli w przyszłości zechcesz zmodyfikować konfigurację strumienia, możesz to zrobić, wysyłając autoryzowane żądanie GET do https://risc.googleapis.com/v1beta/stream, aby pobrać bieżącą konfigurację strumienia, zmodyfikować treść odpowiedzi, a następnie wysłać zmodyfikowaną konfigurację z powrotem do https://risc.googleapis.com/v1beta/stream:update w sposób opisany powyżej.

Zatrzymywanie i wznawianie strumienia zdarzeń

Jeśli chcesz zatrzymać strumień zdarzeń z Google, wyślij autoryzowane żądanie POST do https://risc.googleapis.com/v1beta/stream/status:update z parametrem { "status": "disabled" } w treści żądania. Gdy strumień jest dezaktywowany, Google nie wysyła zdarzeń do punktu końcowego ani nie buforuje zdarzeń związanych z bezpieczeństwem, gdy one wystąpią. Aby ponownie włączyć strumień zdarzeń, wyślij POST { "status": "enabled" } do tego samego punktu końcowego.

3. Opcjonalnie: przetestuj konfigurację strumienia

Możesz sprawdzić, czy konfiguracja strumienia i punkt końcowy odbiornika działają prawidłowo, wysyłając token weryfikacyjny przez strumień zdarzeń. Ten token może zawierać unikalny ciąg znaków, którego możesz użyć do sprawdzenia, czy token został odebrany w Twoim punkcie końcowym. Aby użyć tego procesu, podczas rejestrowania odbiorcy zasubskrybuj typ zdarzenia https://schemas.openid.net/secevent/risc/event-type/verification.

Aby poprosić o token weryfikacyjny, wyślij autoryzowane żądanie HTTPS POST do adresu https://risc.googleapis.com/v1beta/stream:verify. W treści żądania podaj ciąg znaków identyfikujących:

{
  "state": "ANYTHING"
}

Na przykład:

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()))

Jeśli żądanie zostanie wykonane, token weryfikacyjny zostanie wysłany do zarejestrowanego przez Ciebie punktu końcowego. Jeśli na przykład punkt końcowy obsługuje tokeny weryfikacyjne, po prostu je rejestrując, możesz sprawdzić logi, aby potwierdzić, że token został odebrany.

Odniesienie do kodu błędu

Interfejs RISC API może zwracać te błędy:

Kod błędu Komunikat o błędzie Sugerowane działania
400 Konfiguracja strumienia musi zawierać pole $fieldname. Twoje żądanie wysłane do punktu końcowego https://risc.googleapis.com/v1beta/stream:update jest nieprawidłowe lub nie można go przeanalizować. W prośbie uwzględnij $fieldname.
401 Brak autoryzacji. Autoryzacja nie powiodła się. Upewnij się, że do żądania dołączono token autoryzacji oraz że jest on ważny i nie wygasł.
403 Punkt końcowy dostawy musi być adresem URL HTTPS. Punkt końcowy dostawy (czyli punkt końcowy, do którego mają być dostarczane zdarzenia RISC) musi korzystać z protokołu HTTPS. Nie wysyłamy zdarzeń RISC na adresy URL HTTP.
403 Obecna konfiguracja strumienia nie ma metody dostarczania zgodnej ze specyfikacją RISC. W projekcie Google Cloud musi być już skonfigurowana usługa RISC. Jeśli używasz Firebase i masz włączone logowanie przez Google, Firebase będzie zarządzać RISC w Twoim projekcie. Nie będziesz mieć możliwości utworzenia konfiguracji niestandardowej. Jeśli w projekcie Firebase nie używasz logowania przez Google, wyłącz je, a potem spróbuj ponownie po godzinie.
403 Nie znaleziono projektu. Upewnij się, że używasz właściwego konta usługi w odpowiednim projekcie. Możesz używać konta usługi powiązanego z usuniętym projektem. Dowiedz się, jak wyświetlić wszystkie konta usługi powiązane z projektem.
403 Konto usługi musi mieć uprawnienia dostępu do konfiguracji RISC Otwórz projekt API Console i przypisz rolę „Administrator konfiguracji RISC” (roles/riscconfigs.admin) do konta usługi, które wykonuje wywołania w Twoim projekcie, wykonując te instrukcje.
403 Interfejsy API do zarządzania strumieniami powinny być wywoływane tylko przez konto usługi. Więcej informacji o wywoływaniu interfejsów API Google za pomocą konta usługi
403 Punkt końcowy dostawy nie należy do żadnej z domen projektu. Każdy projekt ma zestaw autoryzowanych domen. Jeśli Twój punkt końcowy dostarczania (czyli punkt końcowy, do którego mają być dostarczane zdarzenia RISC) nie jest hostowany w żadnej z tych domen, musisz dodać domenę punktu końcowego do tego zbioru.
403 Aby korzystać z tego interfejsu API, musisz mieć w projekcie skonfigurowanego co najmniej 1 klienta OAuth. RISC działa tylko wtedy, gdy utworzysz aplikację obsługującą logowanie przez Google. To połączenie wymaga klienta OAuth. Jeśli Twój projekt nie ma klientów OAuth, RISC prawdopodobnie nie będzie dla Ciebie przydatny. Dowiedz się więcej o korzystaniu przez Google z protokołu OAuth w przypadku naszych interfejsów API.
403

Nieobsługiwany stan.

Nieprawidłowy stan.

Obecnie obsługujemy tylko stany strumienia „enabled” i „disabled”.
404

Projekt nie ma konfiguracji RISC.

Projekt nie ma konfiguracji RISC, nie można zaktualizować stanu.

Wywołaj punkt końcowy https://risc.googleapis.com/v1beta/stream:update, aby utworzyć nową konfigurację transmisji.
4XX/5XX Nie można zaktualizować stanu. Więcej informacji znajdziesz w szczegółowym komunikacie o błędzie.

Zakresy tokena dostępu

Jeśli zdecydujesz się używać tokenów dostępu do uwierzytelniania w interfejsie RISC API, Twoja aplikacja musi wysyłać żądania dotyczące tych zakresów:

Punkt końcowy Zakres
https://risc.googleapis.com/v1beta/stream/status https://www.googleapis.com/auth/risc.status.readonly LUB 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 LUB 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

Potrzebujesz pomocy?

Najpierw zapoznaj się z sekcją kody błędów. Jeśli nadal masz pytania, opublikuj je na Stack Overflow, dodając tag #SecEvents.