از حساب های کاربری با محافظت بین حساب ها محافظت کنید

اگر برنامه شما به کاربران اجازه می‌دهد با استفاده از Google وارد حساب‌های خود شوند، می‌توانید با گوش دادن و پاسخ دادن به اعلان‌های رویداد امنیتی ارائه‌شده توسط سرویس محافظت از حساب‌های متقابل، امنیت حساب‌های مشترک این کاربران را بهبود ببخشید.

این اعلان‌ها به شما در مورد تغییرات عمده در حساب‌های Google کاربرانتان هشدار می‌دهند، که اغلب می‌تواند پیامدهای امنیتی برای حساب‌های آن‌ها در برنامه شما داشته باشد. به عنوان مثال، اگر حساب Google کاربر ربوده شود، ممکن است از طریق بازیابی حساب ایمیل یا استفاده از یک ورود به سیستم منجر به به خطر افتادن حساب کاربر با برنامه شما شود.

برای کمک به کاهش خطر احتمالی چنین رویدادهایی، Google اشیاء سرویس شما را به نام نشانه‌های رویداد امنیتی ارسال می‌کند. این توکن ها اطلاعات بسیار کمی را نشان می دهند - فقط نوع رویداد امنیتی و زمان وقوع آن و شناسه کاربر آسیب دیده - اما شما می توانید از آنها برای انجام اقدامات مناسب در پاسخ استفاده کنید. به عنوان مثال، اگر حساب Google کاربر به خطر بیفتد، می توانید به طور موقت Sign In With Google را برای آن کاربر غیرفعال کنید و از ارسال ایمیل های بازیابی حساب به آدرس Gmail کاربر جلوگیری کنید.

حفاظت از حساب های متقابل بر اساس استاندارد RISC است که در بنیاد OpenID ایجاد شده است.

بررسی اجمالی

برای استفاده از «محافظت بین حساب» با برنامه یا سرویس خود، باید کارهای زیر را انجام دهید:

  1. پروژه خود را در API Consoleتنظیم کنید.

  2. یک نقطه پایانی گیرنده رویداد ایجاد کنید، که Google نشانه‌های رویداد امنیتی را به آن ارسال می‌کند. این نقطه پایانی مسئول اعتبارسنجی نشانه‌هایی است که دریافت می‌کند و سپس به هر روشی که شما انتخاب می‌کنید به رویدادهای امنیتی پاسخ می‌دهد.

  3. نقطه پایان خود را در Google ثبت کنید تا نشانه‌های رویداد امنیتی را دریافت کنید.

پيش نياز

نشانه‌های رویداد امنیتی را فقط برای کاربران Google دریافت می‌کنید که به سرویس شما اجازه دسترسی به اطلاعات نمایه یا آدرس‌های ایمیل خود را داده‌اند. شما این مجوز را با درخواست profile یا دامنه email دریافت می کنید. جدیدتر Sign In With Google یا Google Sign-in SDK های قدیمی به طور پیش فرض این محدوده ها را درخواست می کنند، اما اگر از تنظیمات پیش فرض استفاده نمی کنید یا اگر مستقیماً به نقطه پایانی OpenID Connect Google دسترسی دارید، مطمئن شوید که حداقل یکی از این موارد را درخواست می کنید. دامنه ها

پروژه ای را در API Consoleراه اندازی کنید

قبل از اینکه بتوانید نشانه های رویداد امنیتی را دریافت کنید، باید یک حساب سرویس ایجاد کنید و API RISC را در پروژهAPI Console خود فعال کنید. باید از همان پروژهAPI Console استفاده کنید که برای دسترسی به خدمات Google، مانند Google Sign-in، در برنامه خود استفاده می‌کنید.

برای ایجاد حساب سرویس:

  1. API ConsoleCredentials page را باز کنید. وقتی از شما خواسته شد، پروژهAPI Consoleرا که برای دسترسی به خدمات Google در برنامه خود استفاده می کنید، انتخاب کنید.

  2. روی ایجاد اعتبارنامه > حساب سرویس کلیک کنید.

  3. با دنبال کردن این دستورالعمل ها ، یک حساب سرویس جدید با نقش مدیر پیکربندی RISC ( roles/riscconfigs.admin ) ایجاد کنید.

  4. یک کلید برای حساب سرویس تازه ایجاد شده خود ایجاد کنید. نوع کلید JSON را انتخاب کنید و سپس روی Create کلیک کنید. وقتی کلید ایجاد شد، یک فایل JSON را دانلود خواهید کرد که حاوی اطلاعات کاربری حساب سرویس شما است. این فایل را در جایی امن نگه دارید، اما همچنین برای نقطه پایانی گیرنده رویدادتان قابل دسترسی باشد.

هنگامی که در صفحه اعتبار پروژه خود هستید، همچنین به شناسه های سرویس گیرنده ای که برای ورود به سیستم با Google یا Google Sign-in استفاده می کنید توجه داشته باشید. به طور معمول، شما برای هر پلتفرمی که پشتیبانی می کنید یک شناسه مشتری دارید. همانطور که در بخش بعدی توضیح داده شد، برای اعتبارسنجی نشانه‌های رویداد امنیتی به این شناسه‌های مشتری نیاز دارید.

برای فعال کردن RISC API:

  1. صفحه RISC API را درAPI Consoleباز کنید. مطمئن شوید پروژه ای که برای دسترسی به خدمات Google استفاده می کنید هنوز انتخاب شده است.

  2. شرایط RISC را بخوانید و مطمئن شوید که شرایط را درک کرده اید.

    اگر API را برای پروژه‌ای که متعلق به یک سازمان است فعال می‌کنید، مطمئن شوید که مجاز هستید سازمان خود را به شرایط RISC ملحق کنید.

  3. تنها در صورتی که با شرایط RISC موافق هستید، روی Enable کلیک کنید.

یک نقطه پایانی گیرنده رویداد ایجاد کنید

برای دریافت اعلان‌های رویداد امنیتی از Google، یک نقطه پایانی HTTPS ایجاد می‌کنید که درخواست‌های HTTPS POST را مدیریت می‌کند. پس از ثبت این نقطه پایانی (به زیر مراجعه کنید)، Google شروع به ارسال رشته های رمزگذاری شده امضا شده به نام نشانه های رویداد امنیتی در نقطه پایانی می کند. نشانه های رویداد امنیتی JWT های امضا شده ای هستند که حاوی اطلاعات مربوط به یک رویداد منفرد مرتبط با امنیت هستند.

برای هر نشانه رویداد امنیتی که در نقطه پایانی خود دریافت می کنید، ابتدا رمز را تأیید و رمزگشایی کنید، سپس رویداد امنیتی را مطابق با سرویس خود مدیریت کنید. برای جلوگیری از حملات مخرب بازیگران بد، اعتبار سنجی نشانه رویداد قبل از رمزگشایی ضروری است. بخش های زیر این وظایف را شرح می دهند:

1. رمزگشایی و اعتبار سنجی نشانه رویداد امنیتی

از آنجا که نشانه‌های رویداد امنیتی نوع خاصی از JWT هستند، می‌توانید از هر کتابخانه JWT، مانند کتابخانه فهرست‌شده در jwt.io ، برای رمزگشایی و اعتبارسنجی آنها استفاده کنید. از هر کتابخانه ای که استفاده می کنید، کد اعتبار سنجی رمز شما باید موارد زیر را انجام دهد:

  1. شناسه صادرکننده محافظت از حساب‌های متقابل ( issuer ) و URI گواهی کلید امضا ( jwks_uri ) را از سند پیکربندی RISC Google دریافت کنید، که می‌توانید آن را در https://accounts.google.com/.well-known/risc-configuration بیابید.
  2. با استفاده از کتابخانه JWT انتخابی خود، شناسه کلید امضا را از سربرگ نشانه رویداد امنیتی دریافت کنید.
  3. از سند گواهینامه کلید امضای گوگل، کلید عمومی را با شناسه کلیدی که در مرحله قبل دریافت کردید، دریافت کنید. اگر سند حاوی یک کلید با شناسه مورد نظر شما نیست، احتمالاً نشانه رویداد امنیتی نامعتبر است و نقطه پایانی شما باید خطای HTTP 400 را برگرداند.
  4. با استفاده از کتابخانه JWT انتخابی خود، موارد زیر را تأیید کنید:
    • نشانه رویداد امنیتی با استفاده از کلید عمومی که در مرحله قبل دریافت کردید امضا می شود.
    • ادعای aud نشانه یکی از شناسه های مشتری برنامه های شما است.
    • ادعای iss توکن با شناسه صادرکننده ای که از سند کشف RISC دریافت کرده اید مطابقت دارد. توجه داشته باشید که نیازی به تأیید انقضای نشانه ( exp ) ندارید زیرا نشانه های رویداد امنیتی نشان دهنده رویدادهای تاریخی هستند و به همین دلیل منقضی نمی شوند.

مثلا:

جاوا

استفاده از java-jwt و 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;
}

پایتون

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)

اگر توکن معتبر است و با موفقیت رمزگشایی شده است، وضعیت HTTP 202 را برگردانید. سپس، رویداد امنیتی نشان داده شده توسط توکن را مدیریت کنید.

2. رسیدگی به رویدادهای امنیتی

هنگام رمزگشایی، یک نشانه رویداد امنیتی مانند مثال زیر است:

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

ادعاهای iss و aud نشان دهنده صادرکننده توکن (Google) و گیرنده مورد نظر توکن (سرویس شما) است. شما این ادعاها را در مرحله قبل تأیید کردید.

ادعای jti رشته‌ای است که یک رویداد امنیتی را مشخص می‌کند و منحصر به جریان است. می توانید از این شناسه برای ردیابی رویدادهای امنیتی که دریافت کرده اید استفاده کنید.

ادعای events حاوی اطلاعاتی درباره رویداد امنیتی است که توکن نشان می دهد. این ادعا یک نگاشت از یک شناسه نوع رویداد به یک ادعای subject است که کاربر مورد نظر این رویداد را مشخص می‌کند و به جزئیات اضافی درباره رویدادی که ممکن است در دسترس باشد.

ادعای subject یک کاربر خاص را با شناسه حساب Google منحصر به فرد کاربر ( sub ) شناسایی می کند. این شناسه حساب Google همان شناسه ( sub ) موجود در نشانه‌های JWT ID است که توسط کتابخانه جدیدتر ورود به سیستم با Google ( جاوا اسکریپت ، HTML )، کتابخانه قدیمی ورود به سیستم Google ، یا OpenID Connect صادر شده است. وقتی subject_type ادعا id_token_claims باشد، ممکن است شامل یک فیلد email با آدرس ایمیل کاربر نیز باشد.

از اطلاعات موجود در ادعای events برای انجام اقدامات مناسب برای نوع رویداد در حساب کاربری مشخص شده استفاده کنید.

شناسه های توکن OAuth

برای رویدادهای OAuth درباره نشانه‌های فردی، نوع شناسه موضوع نشانه شامل فیلدهای زیر است:

  • token_type : فقط refresh_token پشتیبانی می شود.

  • token_identifier_alg : برای مقادیر احتمالی به جدول زیر مراجعه کنید.

  • token : جدول زیر را ببینید.

token_identifier_alg نشانه
prefix 16 کاراکتر اول توکن.
hash_base64_sha512_sha512 هش دوگانه توکن با استفاده از SHA-512.

اگر با این رویدادها ادغام می‌شوید، پیشنهاد می‌شود نشانه‌های خود را بر اساس این مقادیر ممکن فهرست کنید تا از تطابق سریع هنگام دریافت رویداد اطمینان حاصل کنید.

انواع رویدادهای پشتیبانی شده

محافظت بین حساب‌ها از انواع رویدادهای امنیتی زیر پشتیبانی می‌کند:

نوع رویداد ویژگی های نحوه پاسخگویی
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked مورد نیاز : با پایان دادن به جلسات باز فعلی کاربر، حساب کاربری را دوباره ایمن کنید.
https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked

مورد نیاز : اگر رمز برای ورود به سیستم Google است، جلسات باز فعلی آنها را خاتمه دهید. علاوه بر این، ممکن است بخواهید به کاربر پیشنهاد دهید یک روش ورود به سیستم جایگزین را تنظیم کند.

پیشنهادی : اگر رمز برای دسترسی به سایر APIهای Google است، هر یک از نشانه‌های OAuth کاربر را که ذخیره کرده‌اید حذف کنید.

https://schemas.openid.net/secevent/oauth/event-type/token-revoked برای شناسه های توکن به بخش شناسه های توکن OAuth مراجعه کنید

مورد نیاز : اگر رمز به‌روزرسانی مربوطه را ذخیره می‌کنید، آن را حذف کنید و از کاربر درخواست کنید که دفعه بعد که به نشانه دسترسی نیاز است، رضایت مجدد بدهد.

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

الزامی : اگر دلیل غیرفعال شدن حساب کاربری hijacking بود، با پایان دادن به جلسات باز فعلی کاربر، مجدداً حساب کاربری را ایمن کنید.

پیشنهادی : اگر دلیل غیرفعال شدن حساب، bulk-account بود، فعالیت کاربر در سرویس خود را تجزیه و تحلیل کنید و اقدامات بعدی مناسب را تعیین کنید.

پیشنهادی : اگر دلیلی ارائه نشد، Google Sign-in را برای کاربر غیرفعال کنید و بازیابی حساب را با استفاده از آدرس ایمیل مرتبط با حساب Google کاربر (معمولاً، اما نه لزوماً یک حساب Gmail) غیرفعال کنید. یک روش ورود جایگزین به کاربر پیشنهاد دهید.

https://schemas.openid.net/secevent/risc/event-type/account-enabled پیشنهادی : Google Sign-in را مجدداً برای کاربر فعال کنید و بازیابی حساب را با آدرس ایمیل حساب Google کاربر مجدداً فعال کنید.
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required پیشنهاد شده : مراقب فعالیت های مشکوک در سرویس خود باشید و اقدامات لازم را انجام دهید.
https://schemas.openid.net/secevent/risc/event-type/verification حالت = state پیشنهاد شده : ثبت کنید که یک نشانه آزمایشی دریافت شده است.

رویدادهای تکراری و از دست رفته

«حفاظت بین حساب‌ها» تلاش می‌کند رویدادهایی را که معتقد است ارائه نشده‌اند، دوباره ارائه دهد. بنابراین، ممکن است گاهی اوقات یک رویداد را چندین بار دریافت کنید. اگر این می‌تواند باعث اعمال مکرر شود که باعث ناراحتی کاربران شما می‌شود، از ادعای jti (که یک شناسه منحصربه‌فرد برای یک رویداد است) برای حذف رویدادها استفاده کنید. ابزارهای خارجی مانند Google Cloud Dataflow وجود دارد که ممکن است به شما کمک کند تا جریان داده حذف شده را اجرا کنید.

توجه داشته باشید که رویدادها با تلاش‌های مجدد محدود ارائه می‌شوند، بنابراین اگر گیرنده شما برای مدت طولانی خاموش است، ممکن است برخی از رویدادها را برای همیشه از دست بدهید.

گیرنده خود را ثبت کنید

برای شروع دریافت رویدادهای امنیتی، نقطه پایانی گیرنده خود را با استفاده از RISC API ثبت کنید. تماس‌ها با RISC API باید همراه با کد مجوز باشد.

رویدادهای امنیتی را فقط برای کاربران برنامه خود دریافت خواهید کرد، بنابراین باید یک صفحه رضایت OAuth را در پروژه GCP خود به عنوان پیش نیاز مراحل شرح داده شده در زیر پیکربندی کنید.

1. یک نشانه مجوز تولید کنید

برای ایجاد یک نشانه مجوز برای RISC API، یک JWT با ادعاهای زیر ایجاد کنید:

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

JWT را با استفاده از کلید خصوصی حساب سرویس خود امضا کنید، که می توانید آن را در فایل JSON که هنگام ایجاد کلید حساب سرویس دانلود کرده اید، پیدا کنید.

مثلا:

جاوا

استفاده از java-jwt و کتابخانه auth گوگل :

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

پایتون

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

از این نشانه مجوز می توان برای برقراری تماس های RISC API به مدت یک ساعت استفاده کرد. وقتی توکن منقضی شد، یک توکن جدید ایجاد کنید تا به برقراری تماس‌های RISC API ادامه دهید.

2. API پیکربندی جریان RISC را فراخوانی کنید

اکنون که یک نشانه مجوز دارید، می توانید از RISC API برای پیکربندی جریان رویداد امنیتی پروژه خود، از جمله ثبت نقطه پایانی گیرنده خود، استفاده کنید.

برای انجام این کار، یک درخواست HTTPS POST به https://risc.googleapis.com/v1beta/stream:update ، با مشخص کردن نقطه پایانی گیرنده و انواع رویدادهای امنیتی که به آنها علاقه دارید، ارسال کنید:

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

مثلا:

جاوا

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

پایتون

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

اگر درخواست HTTP 200 را برگرداند، جریان رویداد با موفقیت پیکربندی شد و نقطه پایانی گیرنده شما باید نشانه‌های رویداد امنیتی را دریافت کند. بخش بعدی توضیح می‌دهد که چگونه می‌توانید پیکربندی جریان و نقطه پایانی خود را آزمایش کنید تا تأیید کنید همه چیز به درستی با هم کار می‌کند.

پیکربندی جریان فعلی خود را دریافت و به روز کنید

اگر در آینده بخواهید پیکربندی جریان خود را تغییر دهید، می توانید این کار را با درخواست GET مجاز به https://risc.googleapis.com/v1beta/stream انجام دهید تا پیکربندی جریان فعلی را دریافت کنید و بدنه پاسخ را تغییر دهید. و سپس پیکربندی اصلاح شده را به https://risc.googleapis.com/v1beta/stream:update برگردانید همانطور که در بالا توضیح داده شد.

توقف و از سرگیری جریان رویداد

اگر زمانی نیاز به توقف جریان رویداد از Google دارید، یک درخواست مجاز POST به https://risc.googleapis.com/v1beta/stream/status:update با { "status": "disabled" } در بدنه درخواست ارسال کنید. وقتی جریان غیرفعال است، Google رویدادها را به نقطه پایانی شما ارسال نمی‌کند و رویدادهای امنیتی را در صورت وقوع بافر نمی‌کند. برای فعال کردن مجدد جریان رویداد، { "status": "enabled" } در همان نقطه پایانی POST کنید.

3. اختیاری: پیکربندی جریان خود را آزمایش کنید

می‌توانید با ارسال یک نشانه تأیید از طریق جریان رویداد، تأیید کنید که پیکربندی جریان و نقطه پایان گیرنده به درستی با هم کار می‌کنند. این نشانه می‌تواند شامل یک رشته منحصر به فرد باشد که می‌توانید از آن برای تأیید اینکه نشانه در نقطه پایانی شما دریافت شده است استفاده کنید. برای استفاده از این جریان، هنگام ثبت گیرنده، حتماً در https://schemas.openid.net/secevent/risc/event-type/verification نوع رویداد مشترک شوید.

برای درخواست رمز تأیید، یک درخواست HTTPS POST مجاز به https://risc.googleapis.com/v1beta/stream:verify ارسال کنید. در متن درخواست، تعدادی رشته شناسایی را مشخص کنید:

{
  "state": "ANYTHING"
}

مثلا:

جاوا

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

پایتون

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

در صورت موفقیت آمیز بودن درخواست، رمز تأیید به نقطه پایانی که ثبت کرده اید ارسال می شود. سپس، برای مثال، اگر نقطه پایانی شما به سادگی با ثبت کردن توکن‌های تأیید، آنها را کنترل می‌کند، می‌توانید گزارش‌های خود را برای تأیید دریافت نشانه بررسی کنید.

مرجع کد خطا

خطاهای زیر را می توان توسط RISC API برگرداند:

کد خطا پیغام خطا اقدامات پیشنهاد شده
400 پیکربندی جریان باید دارای فیلد $fieldname باشد. درخواست شما به https://risc.googleapis.com/v1beta/stream:update نقطه پایانی نامعتبر است یا قابل تجزیه نیست. لطفاً $fieldname را در درخواست خود وارد کنید.
401 غیرمجاز. مجوز انجام نشد. مطمئن شوید که یک نشانه مجوز را به درخواست پیوست کرده اید و این رمز معتبر است و منقضی نشده است.
403 نقطه پایانی تحویل باید یک URL HTTPS باشد. نقطه پایان تحویل شما (یعنی نقطه پایانی که انتظار دارید رویدادهای RISC به آن تحویل داده شود) باید HTTPS باشد. ما رویدادهای RISC را به URL های HTTP ارسال نمی کنیم.
403 پیکربندی جریان موجود روش تحویل مطابق با مشخصات برای RISC ندارد. پروژه Google Cloud شما باید قبلاً دارای پیکربندی RISC باشد. اگر از Firebase استفاده می کنید و Google Sign-In را فعال کرده اید، Firebase RISC را برای پروژه شما مدیریت می کند. شما نمی توانید یک پیکربندی سفارشی ایجاد کنید. اگر از Google Sign-In برای پروژه Firebase خود استفاده نمی‌کنید، لطفاً آن را غیرفعال کنید و بعد از یک ساعت دوباره سعی کنید به‌روزرسانی کنید.
403 پروژه یافت نشد. مطمئن شوید که از حساب سرویس صحیح برای پروژه صحیح استفاده می کنید. ممکن است از یک حساب سرویس مرتبط با یک پروژه حذف شده استفاده کنید. نحوه مشاهده تمام حساب های خدمات مرتبط با یک پروژه را بیاموزید.
403 حساب سرویس برای دسترسی به پیکربندی RISC شما به مجوز نیاز دارد به API Console پروژه خود بروید و نقش "RISC Configuration Admin" ( roles/riscconfigs.admin ) را به حساب سرویسی که با دنبال کردن این دستورالعمل ها با پروژه شما تماس برقرار می کند اختصاص دهید.
403 APIهای مدیریت جریان فقط باید توسط یک حساب سرویس فراخوانی شوند. در اینجا اطلاعات بیشتری در مورد نحوه تماس با Google API با یک حساب سرویس آورده شده است.
403 نقطه پایان تحویل به هیچ یک از دامنه های پروژه شما تعلق ندارد. هر پروژه دارای مجموعه ای از دامنه های مجاز است. اگر نقطه پایان تحویل شما (یعنی نقطه پایانی که انتظار دارید رویدادهای RISC به آن تحویل داده شود) در یکی از آنها میزبانی نمی شود، ما از شما می خواهیم که دامنه نقطه پایانی را به آن مجموعه اضافه کنید.
403 برای استفاده از این API پروژه شما باید حداقل یک سرویس گیرنده OAuth پیکربندی شده باشد. RISC فقط در صورتی کار می‌کند که برنامه‌ای بسازید که از ورود به سیستم Google پشتیبانی کند. این اتصال به یک سرویس گیرنده OAuth نیاز دارد. اگر پروژه شما هیچ مشتری OAuth ندارد، احتمالاً RISC برای شما مفید نخواهد بود. درباره استفاده Google از OAuth برای API های ما بیشتر بیاموزید.
403

وضعیت پشتیبانی نشده

وضعیت نامعتبر است.

ما در حال حاضر فقط از وضعیت‌های جریان « enabled » و « disabled » پشتیبانی می‌کنیم.
404

پروژه هیچ پیکربندی RISC ندارد.

پروژه هیچ پیکربندی RISC موجود ندارد، نمی تواند وضعیت را به روز کند.

برای ایجاد یک پیکربندی جریان جدید، با https://risc.googleapis.com/v1beta/stream:update نقطه پایانی تماس بگیرید.
4XX/5XX وضعیت به روز رسانی نمی شود. برای اطلاعات بیشتر پیام خطای دقیق را بررسی کنید.

دسترسی به محدوده نشانه

اگر تصمیم به استفاده از نشانه‌های دسترسی برای احراز هویت به RISC API دارید، اینها محدوده‌هایی هستند که برنامه شما باید درخواست کند:

نقطه پایانی محدوده
https://risc.googleapis.com/v1beta/stream/status https://www.googleapis.com/auth/risc.status.readonly یا 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 یا 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

کمک خواستن؟

ابتدا بخش مرجع کد خطا ما را بررسی کنید. اگر هنوز سؤالی دارید، آنها را با برچسب #SecEvents در Stack Overflow پست کنید.