Bảo vệ tài khoản người dùng bằng tính năng Bảo vệ nhiều tài khoản

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Nếu ứng dụng của bạn cho phép người dùng đăng nhập vào tài khoản của họ bằng Google, thì bạn có thể cải thiện tính bảo mật cho những người dùng được chia sẻ này\39; bằng cách lắng nghe và phản hồi các thông báo về sự kiện bảo mật do dịch vụ Bảo vệ nhiều tài khoản cung cấp.

Những thông báo này cảnh báo cho bạn về những thay đổi lớn đối với Tài khoản Google của người dùng. Việc này cũng có thể liên quan đến vấn đề bảo mật đối với tài khoản của họ trên ứng dụng của bạn. Ví dụ: Nếu Tài khoản Google của người dùng bị xâm nhập, thì tài khoản đó có thể bị xâm phạm tài khoản người dùng và việc đăng nhập một lần qua tài khoản email.

Để giúp bạn giảm thiểu rủi ro tiềm ẩn của những sự kiện như vậy, Google sẽ gửi cho bạn các đối tượng dịch vụ có tên là mã thông báo sự kiện bảo mật. Các mã thông báo này hiển thị rất ít thông tin – chỉ loại sự kiện bảo mật và thời điểm xảy ra sự cố, giá trị nhận dạng của người dùng bị ảnh hưởng – nhưng bạn có thể sử dụng các mã thông báo này để thực hiện hành động thích hợp. Ví dụ: nếu Tài khoản Google của người dùng bị xâm nhập, bạn có thể tạm thời vô hiệu hoá tính năng Đăng nhập bằng Google cho người dùng đó và ngăn không cho các email khôi phục tài khoản được gửi tới địa chỉ Gmail của người dùng.

Tính năng Bảo vệ nhiều tài khoản dựa trên tiêu chuẩn RISC được phát triển tại Quỹ OpenID.

Tổng quan

Để sử dụng tính năng Bảo vệ nhiều tài khoản với ứng dụng hoặc dịch vụ của mình, bạn phải hoàn thành các nhiệm vụ sau:

  1. Thiết lập dự án của bạn trong API Console.

  2. Tạo điểm cuối của trình nhận sự kiện để Google gửi các mã thông báo sự kiện bảo mật. Điểm cuối này chịu trách nhiệm xác thực mã thông báo nhận được, sau đó phản hồi các sự kiện bảo mật theo bất kỳ cách nào bạn chọn.

  3. Đăng ký điểm cuối của bạn với Google để bắt đầu nhận mã thông báo sự kiện bảo mật.

Điều kiện tiên quyết

Bạn chỉ nhận được mã thông báo sự kiện bảo mật cho những người dùng Google đã cấp quyền dịch vụ truy cập vào thông tin hồ sơ hoặc địa chỉ email của họ. Bạn sẽ nhận được quyền này bằng cách yêu cầu phạm vi profile hoặc email. Theo mặc định, tính năng mới Đăng nhập bằng Google hoặc SDK Đăng nhập bằng Google sẽ yêu cầu các phạm vi này, nhưng nếu bạn không sử dụng chế độ cài đặt mặc định hoặc nếu bạn truy cập trực tiếp vào thiết bị đầu cuối OpenID Connect của Google, hãy đảm bảo bạn đang yêu cầu ít nhất một trong các phạm vi này.

Thiết lập một dự án trong API Console

Trước khi có thể bắt đầu nhận mã thông báo sự kiện bảo mật, bạn phải tạo một tài khoản dịch vụ và bật API RISC trong dự ánAPI Console của mình. Bạn phải sử dụng chính API Console dự án mà bạn sử dụng để truy cập vào các dịch vụ của Google, chẳng hạn như Đăng nhập bằng Google, trong ứng dụng của mình.

Cách tạo tài khoản dịch vụ:

  1. Mở API Console Credentials page. Khi được nhắc, hãy chọn dự án API Consolemà bạn dùng để truy cập vào các dịch vụ của Google trong ứng dụng của mình.

  2. Nhấp vào Tạo thông tin đăng nhập và gt; tài khoản dịch vụ.

  3. Tạo một tài khoản dịch vụ mới với vai trò Người chỉnh sửa.

  4. Tạo một khoá cho tài khoản dịch vụ mới tạo của bạn. Chọn loại khoá JSON, sau đó nhấp vào Create (Tạo). Khi tạo khoá, bạn sẽ tải tệp JSON chứa thông tin xác thực tài khoản dịch vụ của mình xuống. Giữ tệp này ở nơi an toàn nhưng cũng có thể truy cập vào điểm cuối của trình nhận sự kiện.

Trong khi bạn ở trên trang Thông tin xác thực của dự án, hãy lưu ý cả các mã ứng dụng mà bạn sử dụng để Đăng nhập bằng Google hoặc Đăng nhập bằng Google (cũ). Thông thường, bạn sẽ có mã ứng dụng khách cho mỗi nền tảng mà bạn hỗ trợ. Bạn sẽ cần các mã ứng dụng khách này để xác thực mã thông báo sự kiện bảo mật, như mô tả trong phần tiếp theo.

Cách bật API RISC:

  1. Mở trang API RISC trongAPI Console. Hãy đảm bảo rằng dự án mà bạn sử dụng để truy cập vào các dịch vụ của Google vẫn được chọn.

  2. Đọc Điều khoản của RISC và đảm bảo bạn hiểu các yêu cầu.

    Nếu đang bật API cho dự án thuộc sở hữu của một tổ chức, hãy đảm bảo rằng bạn được ủy quyền để ràng buộc tổ chức của mình với các Điều khoản RISC.

  3. Chỉ nhấp vào Bật nếu bạn đồng ý với Điều khoản RISC.

Tạo điểm cuối của trình nhận sự kiện

Để nhận thông báo về sự kiện bảo mật từ Google, bạn cần tạo một điểm cuối HTTPS xử lý các yêu cầu POST HTTPS. Sau khi bạn đăng ký điểm cuối này (xem bên dưới), Google sẽ bắt đầu đăng các chuỗi được ký bằng mật mã gọi là mã thông báo sự kiện bảo mật đến điểm cuối. Mã thông báo sự kiện bảo mật là các JWT được ký chứa thông tin về một sự kiện liên quan đến bảo mật.

Đối với mỗi mã thông báo sự kiện bảo mật mà bạn nhận được tại điểm cuối, trước tiên, hãy xác thực và giải mã mã thông báo, sau đó xử lý sự kiện bảo mật đó cho phù hợp với dịch vụ của bạn. Bạn cần xác thực mã thông báo sự kiện trước khi giải mã để ngăn chặn các đối tượng tấn công độc hại. Các phần sau đây mô tả những tác vụ này:

1. Giải mã và xác thực mã thông báo sự kiện bảo mật

Vì mã thông báo sự kiện bảo mật là một loại JWT cụ thể, nên bạn có thể sử dụng bất kỳ thư viện JWT nào, chẳng hạn như thư viện được liệt kê trên jwt.io, để giải mã và xác thực các mã đó. Bất kể bạn sử dụng thư viện nào, mã xác thực mã thông báo của bạn phải thực hiện những việc sau:

  1. Lấy mã nhận dạng nhà phát hành Bảo vệ nhiều tài khoản (issuer) và URI chứng chỉ khoá ký (jwks_uri) từ tài liệu cấu hình RISC của Google. Bạn có thể tìm thấy tài liệu này tại https://accounts.google.com/.well-known/risc-configuration.
  2. Sử dụng thư viện JWT mà bạn chọn, lấy mã khoá ký từ tiêu đề của mã thông báo sự kiện bảo mật.
  3. Từ tài liệu chứng chỉ khoá ký của Google, hãy lấy khoá công khai bằng mã khoá bạn nhận được ở bước trước. Nếu tài liệu không chứa khóa có mã nhận dạng mà bạn đang tìm, thì có thể mã thông báo sự kiện bảo mật không hợp lệ và điểm cuối của bạn sẽ trả về lỗi HTTP 400.
  4. Sử dụng thư viện JWT bạn chọn, hãy xác minh những thông tin sau:
    • Mã thông báo sự kiện bảo mật được ký bằng khoá công khai mà bạn nhận được ở bước trước.
    • Thông báo xác nhận quyền sở hữu aud của mã thông báo này là một trong các mã ứng dụng khách của bạn.
    • Thông báo xác nhận quyền sở hữu iss của mã thông báo khớp với giá trị nhận dạng nhà phát hành mà bạn nhận được từ tài liệu khám phá của RISC. Xin lưu ý rằng bạn không cần xác minh mã thông báo sắp hết hạn (exp) vì mã thông báo của sự kiện bảo mật sẽ đại diện cho các sự kiện trong quá khứ. Do đó, đừng hết hạn.

Ví dụ:

Java

Sử dụng 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)

Nếu mã thông báo hợp lệ và được giải mã thành công, hãy trả về trạng thái HTTP 202. Sau đó, hãy xử lý sự kiện bảo mật được biểu thị bằng mã thông báo.

2. Xử lý sự kiện bảo mật

Khi được giải mã, mã thông báo sự kiện bảo mật sẽ có dạng như ví dụ sau:

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

Các thông báo xác nhận quyền sở hữu issaud cho biết nhà phát hành mã thông báo (Google) và người nhận mã thông báo mà bạn mong muốn (dịch vụ của bạn). Bạn đã xác minh các tuyên bố này ở bước trước.

Xác nhận quyền sở hữu jti là một chuỗi xác định một sự kiện bảo mật và là duy nhất đối với luồng. Bạn có thể sử dụng giá trị nhận dạng này để theo dõi những sự kiện bảo mật mà bạn đã nhận được.

Tuyên bố events chứa thông tin về sự kiện bảo mật mà mã thông báo đại diện. Thông báo xác nhận quyền sở hữu này là một bản đồ ánh xạ từ giá trị nhận dạng loại sự kiện đến thông báo xác nhận quyền sở hữu subject. Thông báo này nêu rõ cho người dùng về sự kiện này và mọi thông tin chi tiết khác về sự kiện có thể có.

Xác nhận quyền sở hữu subject xác định một người dùng cụ thể bằng mã Tài khoản Google (sub) duy nhất của người dùng đó. Mã tài khoản Google này giống với giá trị nhận dạng (sub) có trong thư viện mã nhận dạng JWT do thư viện Đăng nhập bằng Google (JavaScript, HTML) cũ, thư viện Đăng nhập bằng Google cũ hoặc OpenID Connect. Khi subject_type của thông báo xác nhận quyền sở hữu là id_token_claims, thì thông báo đó cũng có thể bao gồm một trường email với địa chỉ email của người dùng.

Sử dụng thông tin trong thông báo xác nhận quyền sở hữu events để có biện pháp xử lý thích hợp đối với loại sự kiện trên tài khoản của người dùng được chỉ định.

Giá trị nhận dạng mã thông báo OAuth

Đối với các sự kiện OAuth về các mã thông báo riêng lẻ, loại mã nhận dạng chủ đề mã thông báo chứa các trường sau:

  • token_type: Chỉ hỗ trợ refresh_token.

  • token_identifier_alg: Xem bảng bên dưới để biết các giá trị có thể sử dụng.

  • token: Xem bảng bên dưới.

token_identifier_alg mã thông báo
prefix 16 ký tự đầu tiên của mã thông báo.
hash_base64_sha512_sha512 Hàm băm kép của mã thông báo bằng thuật toán SHA-512.

Nếu tích hợp với những sự kiện này, bạn nên lập chỉ mục mã thông báo của mình dựa trên các giá trị có thể có này để đảm bảo thông tin so khớp nhanh khi nhận được sự kiện.

Các loại sự kiện được hỗ trợ

Chương trình Bảo vệ nhiều tài khoản hỗ trợ những loại sự kiện bảo mật sau đây:

Loại sự kiện Thuộc tính Cách trả lời
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked Bắt buộc: Bảo mật lại tài khoản người dùng bằng cách kết thúc phiên họ đang mở.
https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked

Bắt buộc: Nếu mã thông báo là dành cho tính năng Đăng nhập bằng Google, hãy chấm dứt các phiên hiện đang mở của họ. Ngoài ra, bạn nên đề xuất cho người dùng thiết lập một phương thức đăng nhập thay thế.

Đề xuất: Nếu mã thông báo dùng để truy cập vào các API khác của Google, hãy xoá mọi mã thông báo OAuth mà người dùng đã lưu trữ.

https://schemas.openid.net/secevent/oauth/event-type/token-revoked Xem nội dung Mã nhận dạng mã thông báo OAuth để biết mã nhận dạng mã thông báo

Bắt buộc: Nếu bạn lưu trữ mã làm mới tương ứng, hãy xoá mã đó và yêu cầu người dùng đồng ý lại khi cần sử dụng mã thông báo truy cập.

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

Bắt buộc: Nếu lý do tài khoản bị vô hiệu hóa là hijacking, hãy bảo mật lại tài khoản của người dùng bằng cách kết thúc các phiên họ đang mở.

Đề xuất: Nếu lý do tài khoản bị vô hiệu hóa là bulk-account, hãy phân tích hoạt động của người dùng trên dịch vụ của bạn và xác định các hành động cần theo dõi phù hợp.

Đề xuất: Nếu không có lý do nào, hãy tắt tính năng Đăng nhập bằng Google cho người dùng và tắt tính năng khôi phục tài khoản bằng địa chỉ email liên kết với Tài khoản Google của người dùng (thường nhưng không nhất thiết phải là Tài khoản Gmail). Cung cấp cho người dùng một phương thức đăng nhập thay thế.

https://schemas.openid.net/secevent/risc/event-type/account-enabled Đề xuất: Hãy bật lại tính năng Đăng nhập bằng Google cho người dùng và bật lại tính năng khôi phục tài khoản bằng địa chỉ email Tài khoản Google của người dùng.
https://schemas.openid.net/secevent/risc/event-type/account-purged Đề xuất: Xoá tài khoản của người dùng hoặc cung cấp cho họ một phương thức đăng nhập thay thế.
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required Đề xuất: Đề phòng hoạt động đáng ngờ trên dịch vụ của bạn và thực hiện hành động thích hợp.
https://schemas.openid.net/secevent/risc/event-type/verification trạng thái=state Đề xuất: Ghi nhật ký nhận được mã thông báo thử nghiệm.

Sự kiện bị trùng lặp và bị bỏ lỡ

Chế độ Bảo vệ nhiều tài khoản sẽ cố gắng phân phối lại các sự kiện mà hệ thống cho rằng chưa phân phối. Do đó, đôi khi bạn có thể nhận được cùng một sự kiện nhiều lần. Nếu việc này có thể gây ra những hành động lặp đi lặp lại gây bất tiện cho người dùng, hãy cân nhắc sử dụng thông báo xác nhận quyền sở hữu jti (đây là giá trị nhận dạng duy nhất cho một sự kiện) để loại bỏ các sự kiện trùng lặp. Các công cụ bên ngoài như Luồng dữ liệu Google Cloud có thể giúp bạn thực thi luồng dữ liệu loại bỏ trùng lặp.

Xin lưu ý rằng các sự kiện được phân phối với số lần thử lại hạn chế, vì vậy, nếu bộ thu của bạn không hoạt động trong một khoảng thời gian dài, bạn có thể bỏ lỡ vĩnh viễn một số sự kiện.

Đăng ký người nhận

Để bắt đầu nhận các sự kiện bảo mật, hãy đăng ký điểm cuối của bộ thu bằng API SCSC. Các lệnh gọi đến API RISC phải đi kèm với mã thông báo uỷ quyền.

Bạn sẽ chỉ nhận được sự kiện bảo mật cho người dùng ứng dụng của mình. Vì vậy, bạn cần định cấu hình màn hình xin phép bằng OAuth trong dự án GCP làm điều kiện tiên quyết cho các bước được mô tả bên dưới.

1. Tạo mã thông báo uỷ quyền

Để tạo mã thông báo uỷ quyền cho API RISC, hãy tạo một JWT với các thông báo xác nhận quyền sở hữu sau:

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

Ký JWT bằng khoá riêng tư của tài khoản dịch vụ mà bạn có thể tìm thấy trong tệp JSON mà bạn đã tải xuống khi tạo khoá tài khoản dịch vụ.

Ví dụ:

Java

Sử dụng java-jwtthư viện xác thực của 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')

Bạn có thể sử dụng mã thông báo uỷ quyền này để thực hiện lệnh gọi API RISC trong một giờ. Khi mã thông báo hết hạn, hãy tạo một mã mới để tiếp tục thực hiện lệnh gọi API RISC.

2. Gọi API cấu hình luồng RISC

Giờ đây khi đã có mã thông báo uỷ quyền, bạn có thể sử dụng API RISC để định cấu hình luồng sự kiện bảo mật của dự án, bao gồm cả việc đăng ký thiết bị đầu cuối của bộ thu.

Để làm như vậy, hãy đưa ra yêu cầu POST HTTPS cho https://risc.googleapis.com/v1beta/stream:update, chỉ định điểm cuối của trình nhận và các loại sự kiện bảo mật mà bạn quan tâm:

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

Ví dụ:

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

Nếu yêu cầu trả về HTTP 200, thì sự kiện phát trực tuyến đã được định cấu hình thành công và điểm cuối của trình nhận sẽ bắt đầu nhận mã thông báo sự kiện bảo mật. Phần tiếp theo mô tả cách bạn có thể kiểm thử cấu hình và điểm cuối của luồng để xác minh rằng mọi thứ đều hoạt động chính xác cùng nhau.

Nhận và cập nhật cấu hình phát trực tiếp hiện tại

Trong tương lai, nếu muốn sửa đổi cấu hình luồng, bạn có thể làm vậy bằng cách gửi yêu cầu GET được ủy quyền cho https://risc.googleapis.com/v1beta/stream để nhận cấu hình luồng hiện tại, sửa đổi nội dung phản hồi, sau đó POST lại cấu hình đã sửa đổi lên https://risc.googleapis.com/v1beta/stream:update như mô tả ở trên.

Dừng và tiếp tục luồng sự kiện

Nếu bạn cần dừng luồng sự kiện từ Google, hãy thực hiện một yêu cầu POST được ủy quyền đến https://risc.googleapis.com/v1beta/stream/status:update với { "status": "disabled" } trong nội dung yêu cầu. Mặc dù luồng bị tắt, nhưng Google sẽ không gửi các sự kiện đến điểm cuối của bạn và sẽ không lưu các sự kiện bảo mật vào bộ đệm khi các sự kiện đó xảy ra. Để kích hoạt lại sự kiện phát trực tiếp, hãy đăng { "status": "enabled" } lên cùng một điểm cuối.

3. Không bắt buộc: Kiểm tra cấu hình của sự kiện trực tiếp

Bạn có thể xác minh rằng cấu hình luồng và điểm cuối của bộ thu hoạt động đúng cách bằng cách gửi mã thông báo xác minh thông qua luồng sự kiện. Mã thông báo này có thể chứa một chuỗi duy nhất bạn có thể sử dụng để xác minh rằng mã thông báo đã nhận được tại điểm cuối của bạn.

Để yêu cầu mã xác minh, hãy gửi một yêu cầu POST HTTPS được phép tới https://risc.googleapis.com/v1beta/stream:verify. Trong phần nội dung của yêu cầu, hãy xác định một số chuỗi xác định:

{
  "state": "ANYTHING"
}

Ví dụ:

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

Nếu yêu cầu thành công, mã xác minh sẽ được gửi đến điểm cuối mà bạn đã đăng ký. Sau đó, chẳng hạn như nếu điểm cuối của bạn xử lý các mã thông báo xác minh bằng cách ghi nhật ký đơn giản, bạn có thể kiểm tra nhật ký để xác nhận mã thông báo đã nhận được.

Tham chiếu mã lỗi

API RISC có thể trả về các lỗi sau:

Mã lỗi Thông báo lỗi Hành động đề xuất
400 Cấu hình luồng phải chứa trường $fieldname. Yêu cầu của bạn đối với điểm cuối https://risc.googleapis.com/v1beta/stream:update là không hợp lệ hoặc không thể phân tích cú pháp. Vui lòng bao gồm $fieldname trong yêu cầu của bạn.
401 Không được uỷ quyền. Ủy quyền không thành công. Hãy đính kèm một mã thông báo uỷ quyền trong yêu cầu. Mã thông báo này là hợp lệ và chưa hết hạn.
403 Điểm cuối phân phối phải là một URL loại HTTPS. Điểm cuối phân phối của bạn (tức là điểm cuối mà bạn mong đợi sự kiện RISC sẽ được phân phối) phải là HTTPS. Chúng tôi không gửi sự kiện RISC tới URL HTTP.
403 Cấu hình luồng hiện có không có cách phân phối tuân thủ thông số kỹ thuật đối với RISC. Dự án Google Cloud của bạn phải có cấu hình RISC. Nếu bạn đang sử dụng Firebase và đã bật tính năng Đăng nhập bằng Google, thì Firebase sẽ quản lý RISC cho dự án của bạn; bạn sẽ không thể tạo cấu hình tuỳ chỉnh. Nếu bạn không sử dụng tính năng Đăng nhập bằng Google cho dự án Firebase của mình, vui lòng tắt tính năng này rồi thử cập nhật lại sau một giờ.
403 Không tìm thấy dự án nào. Hãy đảm bảo bạn đang sử dụng đúng tài khoản dịch vụ cho dự án chính xác. Bạn có thể đang sử dụng một tài khoản dịch vụ có liên kết với một dự án đã xoá. Tìm hiểu cách xem tất cả tài khoản dịch vụ liên kết với một dự án.
403 Tài khoản dịch vụ phải có quyền của người chỉnh sửa trong dự án của bạn. Chuyển đến bảng điều khiển Google Cloud Platform của dự án và cấp tài khoản dịch vụ đang cấp quyền của người chỉnh sửa/chủ sở hữu cho dự án của bạn bằng cách làm theo các hướng dẫn này.
403 Chỉ tài khoản dịch vụ mới có thể gọi API quản lý luồng. Sau đây là thông tin thêm về cách bạn có thể gọi API của Google bằng tài khoản dịch vụ.
403 Điểm cuối phân phối không thuộc bất kỳ miền nào của dự án. Mỗi dự án có một tập hợp miền được ủy quyền. Nếu điểm cuối phân phối của bạn (tức là điểm cuối mà bạn mong đợi sự kiện RISC sẽ được phân phối) không được lưu trữ trên một trong các sự kiện đó, thì bạn cần thêm miền của điểm cuối điểm cuối vào bộ đó.
403 Để sử dụng API này, dự án của bạn phải được định cấu hình ít nhất một ứng dụng OAuth. RISC chỉ hoạt động nếu bạn tạo một ứng dụng hỗ trợ tính năng Đăng nhập bằng Google. Cần có ứng dụng OAuth để kết nối. Nếu dự án của bạn không có ứng dụng OAuth, thì có khả năng RISC sẽ không hữu ích cho bạn. Tìm hiểu thêm về cách Google sử dụng OAuth cho API của chúng tôi.
403

Trạng thái không được hỗ trợ.

Trạng thái không hợp lệ.

Hiện tại, chúng tôi chỉ hỗ trợ các trạng thái của sự kiện trực tiếp "enabled" và "disabled".
404

Dự án không có cấu hình RISC.

Dự án hiện không có cấu hình RISC, không thể cập nhật trạng thái.

Gọi điểm cuối https://risc.googleapis.com/v1beta/stream:update để tạo một cấu hình mới cho sự kiện trực tiếp.
4XX/5XX Không thể cập nhật trạng thái. Hãy kiểm tra thông báo lỗi chi tiết để biết thêm thông tin.

Phạm vi mã thông báo truy cập

Nếu bạn quyết định sử dụng mã truy cập để xác thực với API RISC, thì các phạm vi sau đây mà ứng dụng của bạn phải yêu cầu:

Điểm cuối Phạm vi
https://risc.googleapis.com/v1beta/stream/status https://www.googleapis.com/auth/risc.status.readonly HOẶC 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 HOẶC 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

Bạn cần trợ giúp?

Trước tiên, hãy xem phần tham chiếu mã lỗi của chúng tôi. Nếu bạn vẫn còn thắc mắc, hãy đăng câu hỏi đó trên Stack Overflow và gắn thẻ #SecEvents.