إذا كان تطبيقك يتيح للمستخدمين تسجيل الدخول إلى حساباتهم باستخدام Google، يمكنك تحسين أمان حسابات المستخدمين المشترَكة هذه من خلال الاستماع إلى إشعارات أحداث الأمان التي تقدّمها خدمة "الحماية العابرة للحساب" والردّ عليها.
تُنبّهك هذه الإشعارات بشأن التغييرات الرئيسية في حسابات Google الخاصة بالمستخدمين، والتي يمكن أن يكون لها في كثير من الأحيان أيضًا تبعات أمنية لحساباتهم في تطبيقك. على سبيل المثال، إذا تم الاستيلاء على حساب مستخدم على Google، قد يؤدي ذلك إلى اختراق حساب المستخدم في تطبيقك من خلال استرداد حساب البريد الإلكتروني أو استخدام ميزة "تسجيل الدخول بخطوة واحدة".
لمساعدتك في الحدّ من المخاطر المحتملة لهذه الأحداث، تُرسِل Google عناصر الخدمة التي تُعرف باسم الرموز المميّزة للأحداث الأمنية. لا تعرض هذه الرموز سوى معلومات محدودة جدًا، مثل نوع حدث الأمان ووقت وقوعه ومقاييس أمان المستخدم المتأثر، ولكن يمكنك استخدامها لاتّخاذ الإجراء المناسب رداً على ذلك. على سبيل المثال، إذا تم اختراق حساب مستخدم على Google، يمكنك إيقاف ميزة "تسجيل الدخول باستخدام حساب Google" مؤقتًا لهذا المستخدم و منع إرسال رسائل البريد الإلكتروني الخاصة باسترداد الحساب إلى عنوان Gmail الخاص بالمستخدم.
تستند ميزة "الحماية العابرة للحساب" إلى معيار RISC الذي تم تطويره في مؤسسة OpenID.
نظرة عامة
لاستخدام ميزة "الحماية العابرة للحساب" مع تطبيقك أو خدمتك، عليك إكمال المهام التالية:
إعداد مشروعك في
أنشئ نقطة نهاية لمستقبل الحدث، والتي سترسل إليها Google علامات الأحداث الأمنية. تتحمّل هذه النهاية مسؤوليّة التحقّق من الرموز المميّزة التي تتلقّاها، ثمّ الاستجابة لأحداث الأمان بأيّ طريقة تختارها.
سجِّل نقطة النهاية في Google لبدء تلقّي الرموز المميّزة لأحداث الأمان.
المتطلبات الأساسية
لا تتلقّى سوى الرموز المميّزة لأحداث الأمان لمستخدمي Google الذين منحوا
خدمتك إذن الوصول إلى معلومات ملفهم الشخصي أو عناوين بريدهم الإلكتروني. يمكنك
الحصول على هذا الإذن من خلال طلب النطاقَين profile
أو email
. تطلب حِزم SDK الأحدث لميزة
تسجيل الدخول باستخدام حساب Google أو حِزم SDK القديمة لميزة
تسجيل الدخول باستخدام حساب Google هذه النطاقات تلقائيًا، ولكن
إذا كنت لا تستخدم الإعدادات التلقائية أو إذا كنت تصل إلى نقطة نهاية OpenID
Connect من Google مباشرةً، تأكَّد مما يلي:
أنّك تطلب نطاقًا واحدًا على الأقل من هذه النطاقات.
إعداد مشروع في
قبل أن تتمكّن من بدء تلقّي الرموز المميّزة لأحداث الأمان، عليك إنشاء حساب خدمة وتفعيل واجهة برمجة التطبيقات RISC API في مشروعك. يجب استخدام المشروع نفسه الذي تستخدمه للوصول إلى خدمات Google، مثل ميزة "تسجيل الدخول باستخدام حساب Google"، في تطبيقك.
لإنشاء حساب الخدمة:
افتح . اختَر المشروع الذي تستخدمه للوصول إلى خدمات Google في تطبيقك عندما يُطلب منك ذلك.
انقر على إنشاء بيانات اعتماد > حساب الخدمة.
أنشئ حساب خدمة جديدًا يتضمّن دور "مشرف إعدادات RISC" (
roles/riscconfigs.admin
) باتّباع هذه التعليمات.أنشئ مفتاحًا لحساب الخدمة الذي تم إنشاؤه مؤخرًا. اختَر نوع مفتاح JSON ثم انقر على إنشاء. عند إنشاء المفتاح، ستنزِّل ملف JSON يحتوي على سوى سوى بيانات اعتماد حساب الخدمة. احفظ هذا الملف في مكان آمن، ولكن يمكن أيضًا لنقطة نهاية تلقي الأحداث الوصول إليه.
أثناء تصفُّح صفحة "بيانات الاعتماد" لمشروعك، يُرجى أيضًا تدوين أرقام تعريف العميل التي تستخدمها لميزة "تسجيل الدخول باستخدام حساب Google" أو ميزة "تسجيل الدخول باستخدام حساب Google" (القديمة). عادةً ما يكون لديك معرّف عميل لكل منصّة توفّرها. ستحتاج إلى معرّفات العملاء هذه للتحقّق من صحة علامات حدث الأمان، كما هو موضّح في القسم التالي.
لتفعيل واجهة برمجة التطبيقات RISC API:
افتح صفحة واجهة برمجة التطبيقات RISC في . تأكَّد من أنّ المشروع الذي تستخدمه للوصول إلى خدمات Google لا يزال محدّدًا.
اقرأ بنود RISC وتأكَّد من فهم المتطلبات.
إذا كنت بصدد تفعيل واجهة برمجة التطبيقات لمشروع يملكه معهد، تأكَّد مما يلي: أنّك مفوَّض بربط مؤسستك بأحكام RISC.
لا تنقر على تفعيل إلا إذا وافقت على بنود RISC.
إنشاء نقطة نهاية لمستقبل الأحداث
لتلقّي إشعارات أحداث الأمان من Google، عليك إنشاء نقطة نهاية HTTPS تعالج طلبات POST عبر HTTPS. بعد تسجيل نقطة النهاية هذه (راجِع المعلومات أدناه)، ستبدأ Google في نشر سلاسل موقَّعة تشفيريًا تُعرف باسم رموزها المميّزة للأحداث الأمنية إلى نقطة النهاية. علامات أمان الأحداث هي علامات JWT موقَّعة تحتوي على معلومات عن حدث واحد متعلّق بالأمان.
بالنسبة إلى كل رمز مميّز لحدث أمان تتلقّاه في نقطة النهاية، عليك أولاً التحقّق من صحة الرمز المميّز و فك ترميزه، ثم معالجة الحدث الأمني بما يناسب خدمتك. من الضروري التحقّق من صحة رمز حدث الالتقاط قبل فك ترميزه لمنع الهجمات الخبيثة من الجهات الفاعلة السيئة. توضّح الأقسام التالية هذه المهام:
1. فك ترميز الرمز المميّز لحدث الأمان والتحقّق منه
بما أنّ الرموز المميّزة لأحداث الأمان هي نوع معيّن من الرموز المميّزة لبروتوكول JWT، يمكنك استخدام أي مكتبة لترميز JWT، مثل المكتبة المدرَجة على jwt.io، لفك ترميزها والتحقّق من صحتها. بغض النظر عن المكتبة التي تستخدمها، يجب أن يؤدي رمز التحقّق من الرمز المميّز إلى تنفيذ ما يلي:
- احصل على معرّف جهة إصدار ميزة "الحماية على مستوى الحسابات" (
issuer
) ومعرّف الموارد المنتظم (URI) لشهادة مفتاح التوقيع (jwks_uri
) من مستند إعداد RISC من Google، والذي يمكنك العثور عليه على الرابط:https://accounts.google.com/.well-known/risc-configuration
. - باستخدام مكتبة JWT التي تختارها، يمكنك الحصول على رقم تعريف مفتاح التوقيع من العنوان للرمز المميّز لحدث الأمان.
- من مستند شهادة مفتاح التوقيع من Google، احصل على المفتاح العام باستخدام معرّف المفتاح الذي حصلت عليه في الخطوة السابقة. إذا لم يحتوي المستند على مفتاح بالمعرّف الذي تبحث عنه، من المرجّح أن يكون الرمز المميّز لحدث الأمان غير صالح، ومن المفترض أن تعرض نقطة النهاية خطأ HTTP 400.
- باستخدام مكتبة 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:
// ?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:
# ?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
claim هي سلسلة تحدّد حدثًا أمنيًا واحدًا، وهي
فريدة للمصدر. يمكنك استخدام هذا المعرّف لتتبُّع أحداث الأمان التي تلقّيتها.
تحتوي المطالبة events
على معلومات عن الحدث الأمني الذي يمثّله الرمز المميّز. هذه المطالبة هي تعيين من معرّف نوع الحدث إلى subject
مطالبة، والتي تحدّد المستخدم الذي يرتبط به هذا الحدث، وأي تفاصيل إضافية
قد تكون متاحة عن الحدث.
تحدِّد المطالبة subject
مستخدمًا معيّنًا باستخدام رقم تعريف فريد لحسابه على Google (sub
). وهذا رقم التعريف هو نفسه المعرّف (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 أخرى، احذِف أيًا من رموز 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 |
إجراء مطلوب: إذا كان سبب إيقاف الحساب هو
إجراء مقترَح: إذا كان سبب إيقاف الحساب هو
إجراء مقترَح: في حال عدم تقديم أي سبب، يمكنك إيقاف ميزة "تسجيل الدخول باستخدام حساب 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 API. يجب أن تكون طلبات البيانات من واجهة برمجة التطبيقات RISC API مصحوبة برمز موافقة مميّز.
لن تتلقّى أحداث الأمان إلا لمستخدمي تطبيقك، لذا عليك ضبط شاشة موافقة OAuth في مشروعك على Google Cloud Platform كشرط أساسي للخطوات الموضّحة أدناه.
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
باستخدام 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 API.
2. استدعاء واجهة برمجة التطبيقات لإعداد بث 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 ] }
على سبيل المثال:
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 الأحداث
إلى نقطة النهاية ولا تخزّن أحداث الأمان مؤقتًا عند حدوثها. لإعادة تفعيل بث الأحداث، أرسِل { "status": "enabled" }
إلى نقطة النهاية نفسها.
3- اختياري: اختبار إعدادات البث
يمكنك التحقّق من أنّ إعدادات البث ونقطة نهاية المُستلِم تعملان معًا بشكلٍ صحيح من خلال إرسال رمز مميّز لإثبات الهوية من خلال بث الأحداث. يمكن أن يحتوي هذا الرمز المميّز على سلسلة فريدة يمكنك استخدامها للتحقّق من تلقّي الرمز المميّز في نقطة النهاية. لاستخدام هذه العملية، احرص على الاشتراك في نوع الحدث https://schemas.openid.net/secevent/risc/event-type/verification عند تسجيل جهاز الاستقبال.
لطلب رمز مميّز لإثبات الملكية، قدِّم طلب POST مفوَّضًا عبر HTTPS إلى 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 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"، ستتولّى Firebase إدارة ميزة "الوصول المحدود بموجب سياسة الخدمات المصرفية للأفراد (RISC)" لمشروعك، ولن تتمكّن من إنشاء إعدادات مخصّصة. إذا لم تكن تستخدِم ميزة "تسجيل الدخول باستخدام حساب Google" لمشروعك على Firebase، يُرجى إيقافها، ثم محاولة التحديث مرة أخرى بعد ساعة. |
403 | تعذّر العثور على المشروع. | تأكَّد من استخدام حساب الخدمة الصحيح لمشروع معيّن. قد تكون تستخدِم حساب خدمة مرتبطًا بمشروع تم حذفه. تعرَّف على كيفية الاطّلاع على جميع حسابات الخدمة المرتبطة بمشروع. |
403 | يحتاج حساب الخدمة إلى إذن للوصول إلى إعدادات RISC . | انتقِل إلى مشروعك
ومنح الدور "مشرف إعداد RISC"
(roles/riscconfigs.admin )
إلى حساب الخدمة الذي يُجري المكالمات إلى مشروعك من خلال
اتّباع
هذه التعليمات.
|
403 | يجب ألا يستدعي أي حساب آخر سوى حساب الخدمة واجهات برمجة التطبيقات لإدارة البث. | في ما يلي مزيد من المعلومات عن كيفية استدعاء Google APIs باستخدام حساب خدمة. |
403 | لا تنتمي نقطة نهاية الإرسال إلى أيّ من نطاقات مشروعك. | يتضمّن كل مشروع مجموعة من النطاقات المعتمَدة. إذا لم تكن نقطة نهاية الإرسال (أي نقطة النهاية التي تتوقّع أن يتم إرسال أحداث RISC إليها) مستضافة على أحدهما، نطلب منك إضافة نطاق نقطة النهاية إلى هذه المجموعة. |
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 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 |
هل تحتاج إلى مساعدة؟
أولاً، اطّلِع على قسم مرجع رموز الخطأ. إذا كانت لديك أسئلة أخرى، يمكنك طرحها على Stack Overflow باستخدام العلامة #SecEvents.