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

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

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

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

محافظت از حساب‌های کاربری متقابل (Cross-Account Protection) بر اساس استاندارد RISC است که در بنیاد OpenID توسعه داده شده است.

نمای کلی

برای استفاده از محافظت بین حساب‌های کاربری (Cross-Account Protection) در برنامه یا سرویس خود، باید مراحل زیر را انجام دهید:

  1. پروژه خود را در API Console.

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

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

پیش‌نیاز

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

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

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

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

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

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

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

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

وقتی در صفحه اعتبارنامه‌های پروژه خود هستید، شناسه‌های کلاینتی که برای ورود با گوگل یا ورود با گوگل (قدیمی) استفاده می‌کنید را نیز یادداشت کنید. معمولاً برای هر پلتفرمی که پشتیبانی می‌کنید، یک شناسه کلاینت دارید. همانطور که در بخش بعدی توضیح داده شده است، برای اعتبارسنجی توکن‌های رویداد امنیتی به این شناسه‌های کلاینت نیاز خواهید داشت.

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

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

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

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

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

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

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

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

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

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

  1. شناسه صادرکننده حفاظت بین حساب ( issuer ) و آدرس اینترنتی گواهی کلید امضا ( jwks_uri ) را از سند پیکربندی RISC گوگل دریافت کنید که می‌توانید آن را در 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 را برگردانید. سپس، رویداد امنیتی مشخص شده توسط توکن را مدیریت کنید.

۲. مدیریت رویدادهای امنیتی

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

{
  "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 نشان‌دهنده صادرکننده توکن (گوگل) و گیرنده مورد نظر توکن (سرویس شما) هستند. شما این ادعاها را در مرحله قبل تأیید کردید.

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

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

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

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

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

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

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

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

  • token : به جدول زیر مراجعه کنید.

token_identifier_alg توکن
prefix ۱۶ کاراکتر اول توکن.
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

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

پیشنهاد : اگر توکن برای دسترسی به سایر APIهای گوگل است، هر یک از توکن‌های 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 بوده است، فعالیت کاربر را در سرویس خود تجزیه و تحلیل کرده و اقدامات پیگیری مناسب را تعیین کنید.

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

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

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

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

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

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

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

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

۱. یک توکن مجوز ایجاد کنید

برای تولید یک توکن مجوز برای API RISC، یک 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 ایجاد کنید.

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

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

برای انجام این کار، یک درخواست 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 ارسال کنید.

توقف و از سرگیری پخش رویداد

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

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

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

برای درخواست توکن تأیید، یک درخواست 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()))

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

مرجع کد خطا

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

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

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

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

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

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

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

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

دامنه‌های توکن دسترسی

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

نقطه پایانی محدوده
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 ارسال کنید.