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

Jeśli Twoja aplikacja umożliwia użytkownikom logowanie się na swoje konta za pomocą Google, możesz zwiększyć bezpieczeństwo ich kont, słuchając i odpowiadając na powiadomienia o zdarzeniach związanych z bezpieczeństwem, które są dostarczane przez usługę Ochrona wszystkich kont.

Te powiadomienia informują o istotnych zmianach na kontach Google użytkowników, które często mają też znaczenie dla bezpieczeństwa ich kont w aplikacji. Jeśli na przykład konto Google użytkownika zostanie przejęte, może to potencjalnie doprowadzić do przejęcia jego konta w aplikacji przez odzyskanie hasła e-mail lub za pomocą logowania jednokrotnego.

Aby pomóc Ci zmniejszyć ryzyko związane z takimi zdarzeniami, Google wysyła do Twoich usług obiekty zwane tokenami zdarzeń związanych z bezpieczeństwem. Te tokeny zawierają bardzo mało informacji – tylko typ zdarzenia związanego z bezpieczeństwem, czas jego wystąpienia i identyfikator użytkownika, którego dotyczy problem – ale możesz ich użyć, aby podjąć odpowiednie działania. Jeśli na przykład konto Google użytkownika zostało naruszone, możesz tymczasowo wyłączyć opcję Zaloguj się przez Google dla tego użytkownika i zapobiec wysyłaniu e-maili dotyczących przywracania konta na adres Gmail użytkownika.

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

Omówienie

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 weryfikowanie otrzymanych tokenów, a następnie reagowanie na zdarzenia związane z bezpieczeństwem w dowolny wybrany sposób.

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

Warunek wstępny

Otrzymasz tylko tokeny zdarzeń związanych z bezpieczeństwem użytkowników Google, którzy wyrazili zgodę na to, aby Twoja usługa miała dostęp do ich informacji profilowych lub adresów e-mail. Możesz uzyskać to uprawnienie, prosząc o zakres profile lub email. Nowsze pakiety SDK Logowania z Google lub starsze pakiety SDK Logowania z Google domyślnie wymagają 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 używasz 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 projekcieAPI Console . W aplikacji musisz używać tego samego projektuAPI Console , którego używasz do uzyskiwania dostępu do usług Google, takich jak logowanie w Google.

Aby utworzyć konto usługi:

  1. Otwórz API Console Credentials page. Gdy pojawi się taka prośba, wybierz projektAPI Console, 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ą administratora 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 poświadczenia konta usługi. Przechowuj ten plik w bezpiecznym miejscu, ale tak, aby był dostępny dla punktu końcowego odbierającego zdarzenia.

Podczas przeglądania strony Dane logowania w projekcie zwróć też uwagę na identyfikatory klienta, których używasz do logowania się przez Google lub logowania przez Google (starszej wersji). Zwykle masz identyfikator klienta dla każdej obsługiwanej platformy. Aby weryfikować tokeny zdarzeń związanych z bezpieczeństwem, musisz mieć te identyfikatory klientów, jak opisano w następnej sekcji.

Aby włączyć interfejs RISC API:

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

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

    Jeśli włączasz interfejs API w projekcie należącym do organizacji, sprawdź, czy masz uprawnienia do nałożenia na organizację Warunków RISC.

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

Tworzenie punktu końcowego odbiornika zdarzeń

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

W przypadku każdego tokena zdarzenia związanego z bezpieczeństwem, który otrzymasz w punkcie końcowym, najpierw sprawdź i zdekoduj token, a następnie obsłuż zdarzenie związane z bezpieczeństwem zgodnie z wymaganiami usługi. Niezbędne jest sprawdzenie tokenu zdarzenia przed jego odkodowaniem, aby zapobiec złośliwym atakom ze strony nieuczciwych podmiotów. W sekcjach poniżej znajdziesz informacje o tych zadaniach:

1. Odkoduj i zweryfikuj token zdarzenia związanego z bezpieczeństwem

Ponieważ tokeny zdarzeń związanych z bezpieczeństwem to specyficzny rodzaj tokenów JWT, możesz używać dowolnej biblioteki JWT, np. wymienionej na stronie jwt.io, do ich dekodowania i weryfikacji. Niezależnie od tego, której biblioteki używasz, kod weryfikacji tokena musi:

  1. Aby uzyskać identyfikator wydawcy (issuer) i identyfikator URI certyfikatu klucza podpisywania (jwks_uri) w ramach ochrony na wielu kontach, skorzystaj z dokumentu konfiguracji RISC Google, który znajdziesz na stronie https://accounts.google.com/.well-known/risc-configuration.
  2. Za pomocą wybranej biblioteki JWT pobierz identyfikator klucza podpisywania z nagłówka tokena zdarzenia bezpieczeństwa.
  3. Z dokumentu certyfikatu klucza podpisującego Google pobierz klucz publiczny z identyfikatorem klucza uzyskanym w poprzednim kroku. Jeśli dokument nie zawiera klucza z wyszukiwanym identyfikatorem, token zdarzenia związanego z bezpieczeństwem jest prawdopodobnie nieprawidłowy, a punkt końcowy powinien zwrócić błąd HTTP 400.
  4. Za pomocą wybranej biblioteki JWT sprawdź te kwestie:
    • Token zdarzenia bezpieczeństwa jest podpisany przy użyciu klucza publicznego uzyskanego w poprzednim kroku.
    • Roszczenie aud w tokenie to jeden z identyfikatorów klienta Twoich aplikacji.
    • Uprawnienie iss w tokenie jest zgodne z identyfikatorem wydawcy uzyskanym z dokumentu RISC. Pamiętaj, że nie musisz weryfikować daty wygaśnięcia tokena (exp), ponieważ tokeny zdarzeń związanych z bezpieczeństwem odzwierciedlają zdarzenia historyczne i w związku z tym nie wygasają.

Na przykład:

Java

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

Jeśli token jest prawidłowy i został zdekodowany, zwracany jest kod stanu 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 dekodowaniu token zdarzenia związanego z bezpieczeństwem wygląda tak:

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

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

Uprawnienie jti to ciąg znaków, który identyfikuje pojedyncze zdarzenie związane z bezpieczeństwem i jest unikalny dla strumienia. Za pomocą tego identyfikatora możesz śledzić, które zdarzenia bezpieczeństwa zostały wysłane.

Uprawnienie events zawiera informacje o zdarzeniu związanym z bezpieczeństwem, które reprezentuje token. To pole jest mapowaniem identyfikatora typu zdarzenia na pole subject, 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.

Założenie subject identyfikuje konkretnego użytkownika za pomocą jego unikalnego identyfikatora konta Google (sub). Ten identyfikator konta Google to ten sam identyfikator (sub), który znajduje się w tokenach identyfikatora JWT wydanych przez nowszą bibliotekę Logowania przez Google (Javascript, HTML), starszą bibliotekę Logowania przez Google lub OpenID Connect. Jeśli subject_type roszczenia to id_token_claims, może ono też zawierać pole email z adresem e-mail użytkownika.

Użyj informacji z roszczenia events, aby podjąć odpowiednie działania w sytuacji typu zdarzenia na koncie wybranego użytkownika.

Identyfikatory tokenów OAuth

W przypadku zdarzeń OAuth dotyczących poszczególnych tokenów typ identyfikatora token subject 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 hasz tokena za pomocą algorytmu SHA-512.

Jeśli chcesz je zintegrować, 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 Wymagany: ponownie zabezpiecz konto użytkownika, kończąc jego otwarte sesje.
https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked

Wymagany: jeśli token jest przeznaczony do logowania w Google, zakończ wszystkie otwarte sesje. Możesz też zasugerować użytkownikowi skonfigurowanie innej metody logowania.

Proponowane: 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 OAuth 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 następnym razem, gdy będzie potrzebny token dostępu.

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

Wymagane: jeśli konto zostało wyłączone z powoduhijacking, ponownie zabezpiecz konto użytkownika, kończąc jego aktualne sesje.

Proponowane: jeśli konto zostało wyłączone z powodubulk-account, przeanalizuj aktywność użytkownika w usłudze i zdecyduj, jakie działania podjąć w następnym kroku.

Proponowane rozwiązanie: jeśli nie podano powodu, wyłącz opcję logowania się w Google dla użytkownika i wyłącz odzyskiwanie konta przy użyciu adresu e-mail powiązanego z kontem Google użytkownika (zwykle, ale nie zawsze, jest to konto Gmail). Zaoferuj użytkownikowi alternatywną metodę logowania.

https://schemas.openid.net/secevent/risc/event-type/account-enabled Proponowane rozwiązanie: ponownie włącz logowanie Google dla użytkownika i ponowne umożliwienie odzyskiwania konta za pomocą adresu e-mail konta Google użytkownika.
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required Sugerowane: sprawdzaj podejrzaną aktywność w usłudze i podejmuj odpowiednie działania.
https://schemas.openid.net/secevent/risc/event-type/verification state=state Sugerowane: odnotowanie otrzymania tokena testowego.

Duplikaty i pominięte zdarzenia

Ochrona wszystkich kont spróbuje ponownie wysłać zdarzenia, które według niej nie zostały dostarczone. Dlatego czasami możesz otrzymywać to samo zdarzenie kilka razy. Jeśli może to powodować powtarzające się działania, które są uciążliwe dla użytkowników, rozważ użycie atrybutu jti (który jest unikalnym identyfikatorem zdarzenia), aby usunąć duplikaty zdarzeń. Istnieją zewnętrzne narzędzia, takie jak Google Cloud Dataflow, które mogą Ci pomóc w wykonaniu deduplikacji danych.

Pamiętaj, że zdarzenia są dostarczane z ograniczoną liczbą prób, więc jeśli odbiorca jest niedostępny przez dłuższy czas, niektóre zdarzenia mogą zostać utracone na zawsze.

Rejestrowanie odbiornika

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

Aby otrzymywać zdarzenia związane z bezpieczeństwem tylko od użytkowników aplikacji, musisz skonfigurować ekran zgody OAuth w projekcie Google Cloud Platform.

1. Generowanie tokena autoryzacji

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

{
  "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 Google do uwierzytelniania:

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 wykonywać wywołania interfejsu RISC API.

2. Wywoływanie interfejsu RISC konfiguracji strumienia

Teraz, gdy masz token autoryzacji, możesz użyć interfejsu RISC API, aby skonfigurować strumień zdarzeń bezpieczeństwa projektu, w tym zarejestrować punkt końcowy odbiorczy.

Aby to zrobić, wyślij żądanie HTTPS POST do adresu https://risc.googleapis.com/v1beta/stream:update, podając punkt końcowy odbiorcy i typy zdarzeń bezpieczeństwa, 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 zwraca kod HTTP 200, oznacza to, że strumień zdarzeń został prawidłowo skonfigurowany i punkt końcowy odbiorcy powinien zacząć otrzymywać tokeny zdarzeń związanych z bezpieczeństwem. W następnej sekcji opisujemy, jak przetestować konfigurację strumienia i punkt końcowy, 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 adresu https://risc.googleapis.com/v1beta/stream, aby pobrać bieżącą konfigurację strumienia, zmodyfikować treść odpowiedzi, a potem przesłać zmodyfikowaną konfigurację z poziomu adresu https://risc.googleapis.com/v1beta/stream:update, jak opisano powyżej.

Wstrzymywanie i wznawianie strumienia zdarzeń

Jeśli kiedykolwiek będziesz potrzebować zatrzymać strumień zdarzeń z Google, prześlij autoryzowane żądanie POST do adresu 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 Twojego punktu końcowego i nie buforuje zdarzeń związanych z bezpieczeństwem, gdy się pojawiają. Aby ponownie włączyć strumień zdarzeń, prześlij { "status": "enabled" } do tego samego punktu końcowego.

3. Opcjonalnie: przetestuj konfigurację strumienia

Aby sprawdzić, czy konfiguracja strumienia i punkt końcowy odbiorczy działają prawidłowo, wyślij token weryfikacyjny przez strumień zdarzeń. Token może zawierać unikalny ciąg znaków, który możesz wykorzystać do potwierdzenia, że token został odebrany w Twoim punkcie końcowym. Aby korzystać z tego procesu, podczas rejestrowania odbiornika 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 identyfikujący:

{
  "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 się powiedzie, token weryfikacyjny zostanie wysłany do zarejestrowanego punktu końcowego. Jeśli na przykład Twój punkt końcowy obsługuje tokeny weryfikacyjne, po prostu je rejestrując, możesz sprawdzić dzienniki, aby potwierdzić, że token został odebrany.

Odwołania do kodów błędów

Interfejs RISC API może zwrócić te błędy:

Kod błędu Komunikat o błędzie Sugerowane działania
400 Konfiguracja strumienia musi zawierać pole $fieldname. Żą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 podaj parametr $fieldname.
401 Brak autoryzacji. Autoryzacja nie powiodła się. Pamiętaj, aby dołączyć do żądania token autoryzacji, który jest prawidłowy i nie wygasł.
403 Punkt końcowy dostawy musi być adresem URL HTTPS. Punkt końcowy przesyłania (czyli punkt końcowy, do którego mają być dostarczane zdarzenia RISC) musi korzystać z protokołu HTTPS. Nie wysyłamy zdarzeń RISC do adresów URL HTTP.
403 Obecna konfiguracja strumienia nie ma zgodnej ze specyfikacją metody dostarczania w przypadku RISC. Twój projekt Google Cloud musi mieć już konfigurację RISC. Jeśli używasz Firebase i masz włączoną funkcję Logowania z Google, Firebase będzie zarządzać RISC w Twoim projekcie. Nie będziesz mieć możliwości utworzenia niestandardowej konfiguracji. Jeśli w swoim projekcie Firebase nie używasz logowania przez Google, wyłącz tę funkcję, a potem po godzinie spróbuj ponownie przeprowadzić aktualizację.
403 Nie udało się znaleźć 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 stronę API Console swojego projektu i przypisz rolę „Administrator konfiguracji RISC” (roles/riscconfigs.admin) do konta usługi, które wysyła wywołania do Twojego projektu. Aby to zrobić, wykonaj 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 Google API 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 punkt końcowy przesyłania (czyli punkt końcowy, do którego mają być dostarczane zdarzenia RISC) nie jest hostowany na jednym z nich, musisz dodać domenę tego punktu końcowego do tego zestawu.
403 Aby korzystać z tego interfejsu API, musisz skonfigurować w projekcie co najmniej 1 klienta OAuth. RISC działa tylko wtedy, gdy tworzysz aplikację, która obsługuje logowanie przez Google. To połączenie wymaga klienta OAuth. Jeśli Twój projekt nie ma żadnych klientów OAuth, prawdopodobnie RISC nie będzie dla Ciebie przydatny. Dowiedz się więcej o używaniu przez Google protokołu OAuth w przypadku 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, więc nie można zaktualizować stanu.

Aby utworzyć nową konfigurację strumienia, wywołaj punkt końcowy https://risc.googleapis.com/v1beta/stream:update.
4XX/5XX Nie można zaktualizować stanu. Aby uzyskać więcej informacji, sprawdź szczegółowy komunikat o błędzie.

Zakresy tokenów dostępu

Jeśli zdecydujesz się używać tokenów dostępu do uwierzytelniania w interfejsie RISC API, aplikacja musi poprosić o te zakresy:

Punkt końcowy Zakres
https://risc.googleapis.com/v1beta/stream/status https://www.googleapis.com/auth/risc.status.readonlyLUB 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.readonlyLUB 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ą Przewodnik po kodach błędów. Jeśli nadal masz pytania, opublikuj je na Stack Overflow, dodając tag #SecEvents.