אם האפליקציה שלך מאפשרת למשתמשים להיכנס לחשבונות שלהם באמצעות Google, אפשר לשפר את אבטחת החשבונות של המשתמשים המשותפים על ידי האזנה להתראות על פעולות אבטחה ומענה להתראות שמסופקות על ידי השירות להגנה על כל החשבונות.
ההתראות האלה מתריעות על שינויים משמעותיים בחשבונות Google של המשתמשים שלכם, ולרוב יכולות להיות לכך גם השלכות על האבטחה של החשבונות שלהם באפליקציה. לדוגמה, אם חשבון Google של משתמש נפרץ, הדבר עלול לגרום לפריצה לחשבון המשתמש באפליקציה על ידי שחזור חשבון אימייל או שימוש בכניסה יחידה.
כדי לעזור למזער את פוטנציאל הסיכון של אירועים כאלה, Google שולחת את האובייקטים של השירות שנקראים אסימונים של אירועי אבטחה. האסימונים האלה חושפים מעט מאוד מידע – רק את הסוג של אירוע האבטחה ומתי הוא התרחש, והמזהה של המשתמש המושפע – אבל אפשר להשתמש בהם כדי לנקוט פעולה מתאימה בתגובה. לדוגמה, אם חשבון Google של משתמש נפרץ, תוכלו להשבית באופן זמני את התכונה'כניסה באמצעות חשבון Google' עבור אותו משתמש ולמנוע שליחה של אימיילים לשחזור החשבון לכתובת Gmail של המשתמש.
ההגנה על כל החשבונות מבוססת על תקן RISC שפותח על ידי OpenID Foundation.
סקירה כללית
כדי להשתמש בהגנה על כל החשבונות באפליקציה או בשירות, צריך לבצע את המשימות הבאות:
הגדרת הפרויקט ב- API Console.
יוצרים נקודת קצה של מקבל אירועים, שאליה Google תשלח אסימונים של אירועי אבטחה. נקודת הקצה (endpoint) הזו אחראית לאימות האסימונים שהיא מקבלת, ולאחר מכן להגיב לאירועי אבטחה בכל דרך שתבחרו.
כדי להתחיל לקבל אסימונים של אירועי אבטחה, צריך לרשום את נקודת הקצה ב-Google.
ידע מוקדם שנדרש לקורס
אתם מקבלים אסימונים של אירועי אבטחה רק למשתמשי Google שהעניקו לשירות שלכם הרשאה לגשת לפרטי הפרופיל או לכתובות האימייל שלהם. כדי לקבל את ההרשאה הזו, צריך לבקש את ההיקפים profile
או email
. כברירת מחדל, ה-SDK החדש יותר של Sign In with Google או ערכות ה-SDK הקודמות של כניסה באמצעות חשבון Google מבקשות את ההיקפים האלה, אבל אם אתם לא משתמשים בהגדרות ברירת המחדל, או אם אתם ניגשים ישירות לנקודת הקצה של OpenID Connect ב-Google, ודאו שאתם מבקשים לפחות אחד מההיקפים האלה.
הגדרת פרויקט ב- API Console
כדי שתוכלו לקבל אסימונים של אירועי אבטחה, עליכם ליצור חשבון שירות ולהפעיל את RISC API בפרויקטAPI Console שלכם. צריך להשתמש באותו פרויקטAPI Console שבו אתם משתמשים כדי לגשת לשירותי Google, כמו כניסה באמצעות חשבון Google, באפליקציה שלכם.
כדי ליצור את חשבון השירות:
פותחים את API Console Credentials page. כשמופיעה בקשה, בוחרים את הפרויקטAPI Consoleשבו משתמשים כדי לגשת לשירותי Google באפליקציה.
לוחצים על Create credentials > חשבון שירות.
יוצרים חשבון שירות חדש עם תפקיד 'אדמין של תצורת RISC' (
roles/riscconfigs.admin
) לפי ההוראות שכאן.יוצרים מפתח לחשבון השירות החדש שיצרתם. בוחרים את סוג מפתח ה-JSON ולוחצים על Create. כשיוצרים את המפתח, מורידים קובץ JSON שמכיל את פרטי הכניסה לחשבון השירות. שומרים את הקובץ במקום בטוח, אבל נגיש גם לנקודת הקצה של מקלט האירועים.
בדף Credentials של הפרויקט, כדאי לשים לב גם למספרי הלקוחות שבהם אתם משתמשים לכניסה באמצעות חשבון Google או לכניסה באמצעות חשבון Google (מדור קודם). בדרך כלל יש לכם מזהה לקוח לכל פלטפורמה שאתם תומכים בה. כדי לאמת אסימונים לאירועי אבטחה, תצטרכו את מזהי הלקוח האלה, כפי שמתואר בחלק הבא.
כדי להפעיל את RISC API:
פותחים את דף RISC API ב-API Console. חשוב לוודא שהפרויקט שבו אתם משתמשים כדי לגשת לשירותי Google עדיין מסומן.
קוראים את תנאי RISC ומוודאים שאתם מבינים את הדרישות.
אם אתם מפעילים את ה-API בפרויקט שבבעלות ארגון, עליכם לוודא שיש לכם הרשאה לחייב את הארגון שלכם לתנאי ה-RISC.
לוחצים על הפעלה רק אם מסכימים לתנאים של RISC.
יצירת נקודת קצה (endpoint) של מקבל האירועים
כדי לקבל התראות על פעולות שמשפיעות על אבטחת החשבון, צריך ליצור נקודת קצה (endpoint) מסוג HTTPS שמטפלת בבקשות HTTPS POST. אחרי שתרשמו את נקודת הקצה (ראו בהמשך), 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:
// 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 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 |
חובה: אם הסיבה להשבתת החשבון הייתה
הצעה: אם הסיבה להשבתת החשבון היא הצעה: אם לא צוינה סיבה, יש להשבית את הכניסה באמצעות חשבון 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 בפרויקט 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
באמצעות 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 API במשך שעה. כשפג תוקף האסימון, צריך ליצור אסימון חדש כדי להמשיך לבצע קריאות ל-RISC API.
2. להפעיל את RISC Stream configuration API
עכשיו, אחרי שיש לכם אסימון הרשאה, תוכלו להשתמש ב-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, מקור האירועים הוגדר בהצלחה ונקודת הקצה של המקבל אמורה להתחיל לקבל אסימונים של אירועי אבטחה. בקטע הבא מוסבר איך לבדוק את ההגדרות של השידור ואת נקודת הקצה (endpoint) כדי לוודא שהכול פועל כמו שצריך ביחד.
קבלה ועדכון של הגדרת השידור הנוכחית
אם בעתיד תרצו לשנות את ההגדרות של מקור הנתונים, תוכלו לעשות זאת על ידי שליחת בקשת 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 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 | נכנסים אל API Console של הפרויקט ומקצים את התפקיד 'RISC Configuration Admin' (roles/riscconfigs.admin ) לחשבון השירות שמבצע את הקריאות לפרויקט, לפי ההוראות האלה.
|
403 | יש להפעיל ממשקי API לניהול שידורים רק באמצעות חשבון שירות. | כאן תוכל לקרוא איך לקרוא ל-Google APIs באמצעות חשבון שירות. |
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, אלה היקפי ההרשאות שהאפליקציה שלכם צריכה לבקש:
נקודת קצה (endpoint) | היקף |
---|---|
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.