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

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

Powiadomienia te informują o ważnych zmianach na kontach Google Twoich użytkowników, które często mogą też zagrażać bezpieczeństwu ich kont w Twojej aplikacji. Jeśli na przykład konto Google użytkownika zostało przejęte, mogło dojść do jego przejęcia w aplikacji przez odzyskanie konta e-mail lub logowanie jednokrotne.

Aby pomóc Ci zminimalizować ryzyko wystąpienia takich zdarzeń, Google wysyła obiekty usług nazywane tokenami zdarzeń zabezpieczeń. Tokeny te ujawniają bardzo mało informacji – jedynie typ i czas wystąpienia zdarzenia związanego z bezpieczeństwem oraz identyfikator użytkownika, którego dotyczy problem, ale można je wykorzystać do podjęcia odpowiednich działań w odpowiedzi. Jeśli na przykład konto Google użytkownika zostało przejęte, możesz tymczasowo wyłączyć w jego przypadku funkcję Zaloguj się przez Google i zapobiec wysyłaniu mu e-maili do odzyskiwania konta na adres Gmail.

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

Opis

Aby korzystać z Ochrony wszystkich kont w swojej 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 odpowiadanie na zdarzenia związane z bezpieczeństwem w 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

Tokeny zdarzeń związanych z bezpieczeństwem otrzymujesz tylko w przypadku tych użytkowników Google, którzy przyznali Twojej usłudze dostęp do swoich informacji profilowych lub adresów e-mail. Aby je uzyskać, poproś o zakresy profile lub email. Nowsze pakiety SDK do logowania się przez Google lub Google Sign-in domyślnie żądają tych zakresów, ale jeśli nie używasz ustawień domyślnych lub uzyskujesz bezpośredni dostęp do punktu końcowego OpenID Connect Google, upewnij się, że wysyłasz żądanie co najmniej jednego z tych zakresów.

Skonfiguruj projekt w: API Console

Zanim zaczniesz otrzymywać tokeny zdarzeń zabezpieczeń, musisz utworzyć konto usługi i włączyć interfejs RISC API w swoim projekcieAPI Console . Aby uzyskać dostęp do usług Google, takich jak Logowanie przez Google, musisz użyć tego samegoAPI Console projektu, którego używasz w swojej aplikacji.

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 korzystania z 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), wykonując te instrukcje.

  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 do konta usługi. Przechowuj ten plik w bezpiecznym miejscu, ale będzie też dostępny dla punktu końcowego odbiornika.

Na stronie „Dane logowania” w projekcie zwróć też uwagę na identyfikatory klienta używane na potrzeby funkcji Zaloguj się przez Google lub Logowanie przez Google (starsza wersja). Zwykle masz identyfikator klienta dla każdej obsługiwanej platformy. Będą one potrzebne do weryfikacji tokenów zdarzeń zabezpieczeń, zgodnie z opisem w następnej sekcji.

Aby włączyć interfejs RISC API:

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

  2. Zapoznaj się z Warunkami korzystania z programu RISC i upewnij się, że dobrze je rozumiesz.

    Jeśli włączasz interfejs API w projekcie należącym do organizacji, sprawdź, czy masz uprawnienia do powiązania swojej organizacji z warunkami RISC.

  3. Kliknij Włącz tylko wtedy, gdy wyrażasz zgodę na Warunki RISC.

Tworzenie punktu końcowego odbiornika zdarzeń

Aby otrzymywać od Google powiadomienia o zdarzeniach związanych z bezpieczeństwem, tworzysz punkt końcowy HTTPS, który obsługuje żądania HTTPS POST. Gdy zarejestrujesz ten punkt końcowy (patrz poniżej), Google zacznie wysyłać w nim zaszyfrowane ciągi znaków nazywane tokenami zdarzeń związanych z bezpieczeństwem. Tokeny zdarzeń zabezpieczeń to podpisane tokeny JWT, które zawierają informacje o jednym zdarzeniu związanym z zabezpieczeniami.

W przypadku każdego tokena zdarzenia związanego z bezpieczeństwem, który otrzymujesz w punkcie końcowym, najpierw sprawdź i zdekoduj token, a następnie obsłużysz zdarzenie zabezpieczeń odpowiednio do Twojej usługi. Weryfikacja tokena zdarzenia przed dekodowaniem jest niezbędna, aby zapobiegać złośliwym atakom ze strony nieuczciwych podmiotów. Opis tych zadań znajdziesz w tych sekcjach:

1. Dekodowanie i weryfikowanie tokena zdarzenia zabezpieczeń

Tokeny zdarzeń zabezpieczeń są konkretnym rodzajem tokena JWT, więc do zdekodowania i walidacji możesz użyć dowolnej biblioteki JWT, np. tej wymienionej w jwt.io. Niezależnie od tego, której biblioteki używasz, kod do weryfikacji tokena musi wykonywać te czynności:

  1. Uzyskaj identyfikator wydawcy usługi Ochrona wszystkich kont (issuer) i identyfikator URI certyfikatu klucza podpisywania (jwks_uri) z dokumentu konfiguracji RISC Google, który jest dostępny 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 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 oczekiwanym identyfikatorem, prawdopodobnie token zdarzenia związanego z bezpieczeństwem jest nieprawidłowy, a punkt końcowy powinien zwracać błąd HTTP 400.
  4. Przy użyciu wybranej biblioteki JWT sprawdź, czy spełnione są te warunki:
    • Token zdarzenia związanego z bezpieczeństwem jest podpisany za pomocą klucza publicznego uzyskanego w poprzednim kroku.
    • Żądanie aud tokena to jeden z identyfikatorów klienta Twoich aplikacji.
    • Żądanie iss tokena jest zgodne z identyfikatorem wydawcy otrzymanym z dokumentu wykrywania RISC. Nie musisz weryfikować daty wygaśnięcia tokena (exp), ponieważ tokeny zdarzeń związanych z bezpieczeństwem reprezentują zdarzenia historyczne i dlatego nie tracą ważności.

Na przykład:

Java

Przy użyciu komponentów 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, zwraca stan HTTP 202. Następnie przetwórz zdarzenie związane z bezpieczeństwem wskazane w tokenie.

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

Po zdekodowaniu token zdarzenia zabezpieczeń 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"
    }
  }
}

deklaracje iss i aud wskazują wydawcę tokena (Google) i docelowego odbiorcy (Twojej usługi). Te roszczenia zostały przez Ciebie zweryfikowane.

Żądanie jti to ciąg znaków identyfikujący jedno zdarzenie związane z bezpieczeństwem i jest unikalny dla strumienia. Możesz używać tego identyfikatora do śledzenia otrzymanych zdarzeń związanych z bezpieczeństwem.

Deklaracja events zawiera informacje o zdarzeniu zabezpieczeń, z którym reprezentuje token. Ta deklaracja stanowi mapowanie z identyfikatora typu zdarzenia na żądanie subject, które określa użytkownika, którego dotyczy to zdarzenie, oraz na wszelkie dodatkowe informacje o zdarzeniu, które mogą być dostępne.

deklaracja subject identyfikuje konkretnego użytkownika dzięki jego unikalnym identyfikatorem konta Google (sub). Identyfikator konta Google jest taki sam jak ten sam identyfikator (sub) zawarty w tokenach identyfikatorów JWT wydanych przez nowszą bibliotekę Sign In with Google (Javascript, HTML), starszą bibliotekę Google Sign-In lub OpenID Connect. Jeśli subject_type żądania ma wartość id_token_claims, może też zawierać pole email z adresem e-mail użytkownika.

Wykorzystaj informacje zawarte w roszczeniu events, aby podjąć odpowiednie działanie w przypadku określonego typu zdarzenia na koncie określonego użytkownika.

Identyfikatory tokenów OAuth

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

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

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

  • token: patrz tabela poniżej.

token_identifier_alg token
prefix Pierwsze 16 znaków tokena.
hash_base64_sha512_sha512 Podwójny hasz tokena z algorytmem SHA-512.

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

Obsługiwane typy zdarzeń

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

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

Wymagane: jeśli token jest przeznaczony do logowania przez Google, zakończ jego aktualnie otwarte sesje. Możesz też zasugerować użytkownikowi ustawienie alternatywnej metody logowania.

Sugerowane: jeśli token służy do 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 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 powodu hijacking, ponownie zabezpiecz konto użytkownika, kończąc jego aktualnie otwarte sesje.

Sugerowane: jeśli przyczyną wyłączenia konta było bulk-account, przeanalizuj aktywność użytkownika w Twojej usłudze i ustal odpowiednie działania.

Sugerowane: jeśli nie podano powodu, wyłącz Logowanie przez Google dla użytkownika i wyłącz odzyskiwanie konta przy użyciu adresu e-mail powiązanego z jego kontem Google (zwykle, ale niekoniecznie, z kontem Gmail). Zaoferuj użytkownikowi alternatywną metodę logowania.

https://schemas.openid.net/secevent/risc/event-type/account-enabled Sugerowane: jeszcze raz włącz Logowanie przez Google użytkownika i odzyskiwanie konta przy użyciu adresu e-mail konta Google użytkownika.
https://schemas.openid.net/secevent/risc/event-type/account-purged Sugerowane: usuń konto użytkownika lub udostępnij mu alternatywną metodę logowania.
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required Sugerowana aktywność: 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: rejestruj otrzymanie tokena testowego.

Zduplikowane i pominięte wydarzenia

Ochrona wszystkich kont spróbuje ponownie przesłać zdarzenia, jeśli jej zdaniem nie zostały dostarczone. Dlatego czasami to samo zdarzenie może wystąpić kilka razy. Jeśli mogłoby to powodować powtarzające się działania niekorzystne dla użytkowników, rozważ usunięcie duplikatów zdarzeń za pomocą żądania jti (jest to unikalny identyfikator zdarzenia). Istnieją narzędzia zewnętrzne, takie jak Google Cloud Dataflow, które mogą pomóc w wykonaniu przepływu danych do usuwania duplikatów.

Pamiętaj, że wydarzenia są dostarczane z ograniczoną liczbą ponownych prób, więc jeśli odbiorca nie będzie przez dłuższy czas dostępny, możesz trwale przegapić niektóre wydarzenia.

Rejestrowanie odbiornika

Aby zacząć odbierać zdarzenia związane z bezpieczeństwem, zarejestruj punkt końcowy odbiorcy za pomocą interfejsu API RISC. Wywołaniom interfejsu RISC API musi towarzyszyć token autoryzacji.

Zdarzenia związane z bezpieczeństwem będą rejestrowane tylko w przypadku użytkowników aplikacji. W takim przypadku w projekcie GCP musisz skonfigurować ekran zgody OAuth.

1. Generowanie tokena autoryzacji

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

{
  "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. Znajdziesz go w pliku JSON pobranym podczas tworzenia klucza konta usługi.

Na przykład:

Java

Przy użyciu 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')

Tego tokena autoryzacji można używać do wykonywania wywołań interfejsu API RISC przez godzinę. Po wygaśnięciu tokena wygeneruj nowy, aby nadal wykonywać wywołania interfejsu RISC API.

2. Wywoływanie interfejsu API konfiguracji strumienia RISC

Po uzyskaniu tokena autoryzacji możesz za pomocą interfejsu RISC API skonfigurować strumień zdarzeń związanych z bezpieczeństwem projektu, w tym zarejestrować punkt końcowy odbiorcy.

Aby to zrobić, wyślij do https://risc.googleapis.com/v1beta/stream:update żądanie HTTPS POST, wskazując punkt końcowy odbiorcy i typy 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 zwraca kod HTTP 200, strumień zdarzeń został skonfigurowany poprawnie, a 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.

Pobierz i zaktualizuj bieżącą konfigurację 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 WPISAĆ 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ń od 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 wyłączony, Google nie wysyła zdarzeń do punktu końcowego ani nie buforuje zdarzeń związanych z bezpieczeństwem, gdy się pojawią. Aby ponownie włączyć strumień zdarzeń, OPUBLIKUJ { "status": "enabled" } w tym samym punkcie końcowym.

3. Opcjonalnie: testowanie konfiguracji strumienia

Możesz sprawdzić, czy konfiguracja strumienia i punkt końcowy odbiorcy współpracują prawidłowo, wysyłając token weryfikacyjny za pomocą strumienia zdarzeń. Może on zawierać unikalny ciąg znaków, którego możesz użyć do sprawdzenia, czy token został odebrany w punkcie końcowym. Aby skorzystać z 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 https://risc.googleapis.com/v1beta/stream:verify. W treści żądania podaj ciąg znaków 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 punkt końcowy obsługuje tokeny weryfikacyjne po prostu je rejestruje, możesz sprawdzić logi, aby potwierdzić, że token został odebrany.

Informacje o kodzie 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. Żądanie wysyłane do punktu końcowego https://risc.googleapis.com/v1beta/stream:update jest nieprawidłowe lub nie można go przeanalizować. Dołącz do zgłoszenia pole $fieldname.
401 Brak autoryzacji. Autoryzacja nie powiodła się. Sprawdź, czy do żądania został dołączony token autoryzacji, czy token jest prawidłowy i nie stracił ważności.
403 Punkt końcowy wyświetlania musi być adresem URL HTTPS. Punkt końcowy dostarczania (tzn. punkt końcowy, do którego mają być dostarczane zdarzenia RISC) musi używać protokołu HTTPS. Nie wysyłamy zdarzeń RISC do adresów URL HTTP.
403 Istniejąca konfiguracja strumienia nie ma zgodnej ze specyfikacją metody przesyłania dla RISC. Twój projekt Google Cloud musi już mieć konfigurację RISC. Jeśli korzystasz z 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 nie korzystasz w swoim projekcie Firebase z logowania przez Google, wyłącz go i za godzinę spróbuj jeszcze raz przeprowadzić aktualizację.
403 Nie udało się znaleźć projektu. Sprawdź, czy używasz właściwego konta usługi dla właściwego projektu. Być może używasz 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 potrzebuje uprawnień dostępu do konfiguracji RISC Przejdź do sekcji API Console swojego projektu i przypisz rolę „Administrator konfiguracji RISC” (roles/riscconfigs.admin) do konta usługi, które wywołuje Twój projekt, wykonując te instrukcje.
403 Interfejsy API do zarządzania strumieniami powinny być wywoływane tylko przez konto usługi. Dowiedz się więcej o tym, jak wywoływać interfejsy API Google za pomocą konta usługi.
403 Punkt końcowy dostarczania nie należy do żadnej z domen Twojego projektu. Każdy projekt ma zbiór autoryzowanych domen. Jeśli punkt końcowy dostarczania (czyli punkt końcowy, do którego mają być dostarczane zdarzenia RISC) nie jest hostowany w jednym z nich, musisz dodać do tego zbioru domenę punktu końcowego.
403 Aby używać 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 klientów OAuth, prawdopodobnie RISC nie będzie dla Ciebie przydatny. Dowiedz się więcej o korzystaniu przez Google z protokołu OAuth na potrzeby interfejsów API.
403

Stan nieobsługiwany.

Nieprawidłowy stan.

Obecnie obsługujemy tylko stany transmisji „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ę strumienia.
4XX/5XX Nie można zaktualizować stanu. Więcej informacji znajdziesz w szczegółowym komunikacie o błędzie.

Zakresy tokenów dostępu

Jeśli zdecydujesz się używać tokenów dostępu do uwierzytelniania w interfejsie RISC API, Twoja aplikacja musi żądać 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ą Informacje na temat kodów błędów. Jeśli nadal masz pytania, publikuj je na stronie Stack Overflow, używając tagu #SecEvents.