حماية حسابات المستخدمين باستخدام ميزة "الحماية العابرة للحساب"

إذا كان تطبيقك يسمح للمستخدمين بتسجيل الدخول إلى حساباتهم باستخدام Google، يمكنك تحسين على أمان حسابات هؤلاء المستخدمين من خلال الاستماع والاستجابة إشعارات الأحداث الأمنية التي تقدّمها خدمة "الحماية العابرة للحساب"

تنبهك هذه الإشعارات بالتغييرات الكبيرة في حسابات Google لحسابك في المستخدمين، الأمر الذي قد يكون له في كثير من الأحيان آثار أمنية على حساباتهم باستخدام تطبيقك. على سبيل المثال، إذا تم اختراق حساب أحد المستخدمين على Google، يمكن أن إلى اختراق حساب المستخدم من خلال تطبيقك عبر البريد الإلكتروني استرداد الحساب أو استخدام الدخول الموحّد.

لمساعدتك في الحدّ من المخاطر المُحتمَلة لمثل هذه الأحداث، ترسل Google إليك تسمى الرموز المميزة للأحداث الأمنية. تكشف هذه الرموز عن القليل جدًا المعلومات؛ فقط نوع الحدث الأمني ووقت وقوعه، معرّف المستخدم المتأثر - ولكن يمكنك استخدامها لاتخاذ الإجراء المناسب في الرد. على سبيل المثال، إذا تم إنشاء حساب Google لأحد المستخدمين يمكنك تعطيل ميزة "تسجيل الدخول باستخدام حساب Google" مؤقتًا لهذا المستخدم منع إرسال الرسائل الإلكترونية المخصصة لاسترداد الحساب إلى عنوان المستخدم على Gmail.

تستند ميزة "الحماية العابرة للحساب" إلى معيار RISC، الذي تم تطويره في مؤسسة OpenID.

نظرة عامة

لاستخدام ميزة "الحماية العابرة للحساب" مع تطبيقك أو خدمتك، عليك إكمال المهام التالية:

  1. يمكنك إعداد مشروعك في API Console.

  2. إنشاء نقطة نهاية لمتلقي الحدث، والتي سترسل Google إليها الحدث الأمني الرموز المميزة. نقطة النهاية هذه مسؤولة عن التحقق من صحة الرموز المميزة التي تتلقاها ومن ثم الاستجابة لأحداث الأمان بأية طريقة تختارها.

  3. سجِّل نقطة النهاية لدى Google لبدء تلقّي الرموز المميّزة للحدث الأمني.

المتطلبات الأساسية

لن تتلقّى الرموز المميّزة للحدث الأمني إلا لمستخدمي Google الذين منحوا إذن الوصول إلى معلومات ملفه الشخصي أو عناوين البريد الإلكتروني. إِنْتَ الحصول على هذا الإذن من خلال طلب النطاقَين "profile" أو "email" الأحدث تسجيل الدخول باستخدام حساب Google أو الإصدار القديم تطلب حِزم تطوير البرامج (SDK) الخاصة بتسجيل الدخول بحساب Google هذه النطاقات تلقائيًا، ولكن أو إذا لم تستخدم الإعدادات الافتراضية، أو إذا تمكنت من الوصول إلى OpenID من Google ربط نقطة النهاية مباشرةً فأنت تطلب واحدًا على الأقل من هذه النطاقات.

إعداد مشروع في API Console

قبل أن تتمكّن من بدء تلقّي الرموز المميّزة للحدث الأمني، عليك إنشاء خدمة. وتفعيل RISC API في API Console . يجب عليك استخدام نفس API Console المشروع الذي تستخدمه للوصول إلى خدمات Google، مثل تسجيل الدخول بحساب Google، في تطبيقك

لإنشاء حساب الخدمة:

  1. افتح API Console. Credentials page عندما يُطلب منك، اختَر API Console المشروع الذي تستخدمه للوصول إلى خدمات Google في تطبيقك.

  2. انقر على إنشاء بيانات اعتماد > حساب الخدمة:

  3. إنشاء حساب خدمة جديد باستخدام دور "مشرف إعداد RISC" (roles/riscconfigs.admin) عن طريق المتابعة هذه التعليمات.

  4. أنشِئ مفتاحًا لحساب الخدمة الذي أنشأته حديثًا. اختيار مفتاح JSON اكتب ثم انقر على إنشاء. عند إنشاء المفتاح، سيتم تنزيل ملف JSON يحتوي على حساب الخدمة الخاص بك. بيانات الاعتماد. احتفظ بهذا الملف في مكان آمن، ولكن يمكن الوصول إليه أيضًا من خلال نقطة نهاية متلقي الحدث.

أثناء تواجدك في صفحة بيانات الاعتماد الخاصة بمشروعك، دوّن أيضًا العميل أرقام التعريف التي تستخدمها في ميزة "تسجيل الدخول باستخدام حساب Google" أو ميزة "تسجيل الدخول باستخدام حساب Google" (الإصدار القديم) عادةً ما يكون لديك معرف عميل لكل المنصة التي تدعمها. ستحتاج إلى أرقام تعريف العملاء هذه للتحقّق من صحة الحدث الأمني. الرموز المميزة، كما هو موضح في القسم التالي.

لتفعيل واجهة برمجة تطبيقات RISC:

  1. افتح صفحة RISC API في API Consoleتأكد من أن المشروع الذي تستخدمه للوصول إلى خدمات Google لا يزال محددًا.

  2. اقرأ بنود RISC وتأكَّد من فهم متطلباتها.

    في حال تفعيل واجهة برمجة التطبيقات لمشروع تملكه مؤسسة، تأكَّد من يحق لك إلزام مؤسستك ببنود RISC.

  3. لا انقر على تفعيل إلا في حال الموافقة على "بنود RISC".

إنشاء نقطة نهاية متلقي الحدث

لتلقّي إشعارات بشأن الأحداث الأمنية من 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. من مستند شهادة مفتاح توقيع Google، يمكنك الحصول على المفتاح العام مع ومعرّف المفتاح الذي حصلت عليه في الخطوة السابقة. إذا لم يكن المستند يحتوي على مفتاح برقم التعريف الذي تبحث عنه، فمن المحتمل أن يكون الرمز المميز للحدث الأمني غير صالح، ومن المفترض أن تعرض نقطة النهاية خطأ HTTP 400.
  4. باستخدام مكتبة JWT التي تختارها، تحقَّق مما يلي:
    • يتم توقيع الرمز المميّز للحدث الأمني باستخدام المفتاح العام الذي حصلت عليه في الخطوة السابقة.
    • المطالبة aud بالرمز المميز هي أحد تطبيقاتك معرِّفات العملاء.
    • تتطابق المطالبة بقيمة iss بالرمز المميّز مع معرّف جهة الإصدار الذي حصلت عليه منه. وثيقة اكتشاف RISC. يُرجى العلم أنّك لست بحاجة إلى التحقّق من انتهاء صلاحية الرمز المميّز (exp) لأنّ تمثّل الرموز المميّزة للحدث الأمني الأحداث السابقة، ولذلك لا تنتهي صلاحيتها.

على سبيل المثال:

Java

استخدام 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;
}

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)

إذا كان الرمز المميّز صالحًا وتم فك ترميزه بنجاح، يمكنك عرض حالة 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 الصادرة عن الميزة الأحدث "تسجيل الدخول باستخدام حساب Google" (JavaScript) أو 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، عليك إنهاء الجلسات المفتوحة حاليًا. بالإضافة إلى ذلك، قد تحتاج إلى اقتراح على المستخدم إعداد طريقة تسجيل دخول بديلة.

مقترح: إذا كان الرمز المميز يهدف إلى الوصول إلى واجهات Google APIs الأخرى، احذف أي من رموز 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" المستخدم وإيقاف استرداد الحساب باستخدام عنوان البريد الإلكتروني المرتبط حساب Google للمستخدم (حساب Gmail عادةً وليس بالضرورة). قدم للمستخدم طريقة تسجيل دخول بديلة.

https://schemas.openid.net/secevent/risc/event-type/account-enabled إجراء مقترَح: يجب إعادة تفعيل ميزة "تسجيل الدخول بحساب Google" للمستخدم وإعادة تفعيلها. استرداد الحساب باستخدام عنوان البريد الإلكتروني لحساب المستخدم على Google.
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required المعلومة المقترَحة: ابحث عن أي نشاط مريب على خدمتك ونفِّذ الإجراء المناسب.
https://schemas.openid.net/secevent/risc/event-type/verification state=state الاقتراح: سجلّ تلقّي رمز مميّز تجريبي

الأحداث المكرّرة والمفائتة

ستحاول ميزة "الحماية العابرة للحساب" إعادة إرسال الأحداث التي تعتقد أنها تتضمّن لم يتم تسليمه. لذلك، قد تتلقى أحيانًا الحدث نفسه عدة مرات. إذا كان هذا قد يتسبب في تكرار إجراءات تسبب إزعاجًا ننصح باستخدام المطالبة jti (وهي معرّف فريد الحدث) لإزالة تكرار الأحداث. وهناك أدوات خارجية مثل Google Cloud Dataflow الذي قد يساعدك في التنفيذ تدفق البيانات لإزالة التكرار.

يُرجى العلم أنّه يتم إرسال الأحداث مع إعادة المحاولة بشكل محدود، وبالتالي إذا كان جهاز الاستقبال معطّلاً. لفترة زمنية طويلة قد تفوتك بعض الأحداث بشكل دائم.

تسجيل جهاز الاستقبال

لبدء تلقّي الأحداث الأمنية، سجِّل نقطة نهاية المستلِم باستخدام واجهة برمجة تطبيقات RISC. يجب أن تكون الطلبات الصادرة إلى واجهة برمجة تطبيقات RISC مصحوبةً برمز تفويض مميّز.

لن تصلك الأحداث الأمنية إلا لمستخدمي تطبيقك، لذا عليك ضبط شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth. في مشروع Google Cloud Platform كشرط أساسي للخطوات الموضحة أدناه.

1. إنشاء رمز مميّز للمصادقة

لإنشاء رمز تفويض مميز لواجهة برمجة تطبيقات 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

يؤدي استخدام java-jwt مكتبة المصادقة من 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')

يمكن استخدام رمز التفويض هذا لإجراء طلبات البيانات من واجهة برمجة التطبيقات RISC لمدة ساعة واحدة. فعندما بعد انتهاء صلاحية الرمز المميز، عليك إنشاء رمز جديد لمتابعة إجراء طلبات البيانات من واجهة برمجة التطبيقات RISC.

2. طلب واجهة برمجة تطبيقات إعداد بث RISC

الآن بعد أن أصبح لديك رمز تفويض مميز، يمكنك استخدام واجهة برمجة تطبيقات 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
  ]
}

على سبيل المثال:

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

إذا كان الطلب يعرض 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 أحداثًا عندما يكون البث غير مفعَّل. إلى نقطة النهاية بدون تخزين مؤقت للأحداث الأمنية عند حدوثها. إلى إعادة تفعيل بث الحدث، POST { "status": "enabled" } إلى نقطة النهاية نفسها.

3- اختياري: اختبار إعدادات البث

يمكنك التحقّق من عمل إعدادات البث ونقطة نهاية المُستلِم. معًا بشكلٍ صحيح عن طريق إرسال رمز تحقُّق مميّز من خلال ساحة مشاركات الأحداث. ومن الممكن أن يحتوي هذا الرمز على سلسلة فريدة يمكنك استخدامها للتحقق من أن الذي تم استلامه في نقطة النهاية لديك. لاستخدام هذا التدفق، تأكد من الاشتراك في https://schemas.openid.net/secevent/risc/event-type/verification نوع الحدث عند تسجيل المستلِم.

لطلب رمز مميز للتحقُّق، يجب تقديم طلب HTTPS POST مخوّل إلى https://risc.googleapis.com/v1beta/stream:verify في نص الطلب، حدِّد بعضًا سلسلة التعريف:

{
  "state": "ANYTHING"
}

على سبيل المثال:

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

إذا نجح الطلب، فسيتم إرسال الرمز المميز للتحقق إلى نقطة النهاية التي تسجيلك. بعد ذلك، على سبيل المثال، إذا كانت نقطة النهاية تتعامل مع الرموز المميزة لإثبات الملكية عن طريق لتسجيلها، يمكنك فحص السجلات للتأكد من أن الرمز المستلمة.

مرجع رمز الخطأ

يمكن عرض الأخطاء التالية من خلال واجهة برمجة تطبيقات RISC:

رمز الخطأ رسالة خطأ الإجراءات المقترَحة
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"، فسيصبح Firebase وإدارة RISC لمشروعك؛ لن تتمكن من إنشاء واجهة مستخدم مخصصة التكوين. إذا لم تكن تستخدم "تسجيل الدخول بحساب Google" لمشروعك على Firebase، يُرجى إيقافه ثم محاولة التحديث مرة أخرى بعد ساعة.
403 تعذّر العثور على المشروع. تأكَّد من استخدام حساب الخدمة الصحيح مشروعك. قد تكون تستخدم حساب خدمة مرتبطًا بحساب محذوف مشروعك. التعلّم طريقة الاطّلاع على كل حسابات الخدمة المرتبطة بمشروع
403 يحتاج حساب الخدمة إلى إذن للوصول إلى RISC. الإعدادات يُرجى الانتقال إلى API Console قم بتعيين "مشرف تهيئة RISC" الدور (roles/riscconfigs.admin) إلى حساب الخدمة الذي يجري الاتصالات لمشروعك من خلال يتابع هذه التعليمات.
403 يجب طلب واجهات برمجة التطبيقات لإدارة البث من خلال حساب خدمة فقط. إليك المزيد من المعلومات عن كيفية طلب بيانات Google APIs باستخدام حساب خدمة.
403 لا تنتمي نقطة نهاية التسليم إلى أي من نطاقات مشروعك. يحتوي كل مشروع على مجموعة من والنطاقات المعتمَدة. إذا كانت نقطة نهاية التسليم (أي نقطة النهاية التي تتوقع أن تسليمه إلى) لم تتم استضافته على إحدى هذه الخدمات، فنطلب منك إضافة نطاق نقطة النهاية على تلك المجموعة.
403 لاستخدام واجهة برمجة التطبيقات هذه، يجب أن يتضمّن مشروعك عميل OAuth واحدًا على الأقل تم إعداده. لا تعمل RISC إلا إذا أنشأت تطبيقًا يتوافق مع تسجيل الدخول باستخدام حساب Google يتطلّب هذا الاتصال توفُّر عميل OAuth. إذا كان مشروعك لا يتضمن بروتوكول OAuth فمن المحتمل ألا تكون RISC مفيدة لك. مزيد من المعلومات حول استخدام Google لبروتوكول OAuth لواجهات برمجة التطبيقات
403

الحالة غير متوافقة.

الحالة غير صالحة.

يمكن فقط استخدام حالات البث "enabled" "disabled" في الوقت الحالي.
404

لم يتم ضبط إعدادات RISC في المشروع.

لا يحتوي المشروع على إعدادات RISC حالية، وبالتالي لا يمكن تعديل الحالة.

يجب طلب نقطة النهاية https://risc.googleapis.com/v1beta/stream:update لإنشاء إعدادات جديدة لمصدر بيانات.
4XX/5XX يتعذّر تحديث الحالة. لمزيد من المعلومات، يُرجى الاطّلاع على رسالة الخطأ التفصيلية.

نطاقات رموز الدخول المميزة

إذا قررت استخدام رموز الدخول للمصادقة على واجهة برمجة تطبيقات 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

هل تحتاج إلى مساعدة؟

أولاً، يمكنك الاطّلاع على قسم مرجع رموز الخطأ. إذا كنت لا تزال أسئلة، انشرها على Stack Overflow #SecEvents .