אם האפליקציה שלכם מאפשרת למשתמשים להיכנס לחשבונות שלהם באמצעות Google, תוכלו לשפר את האבטחה של החשבונות המשותפים האלה על ידי הקשבה להתראות על אירועי אבטחה שמתקבלות מהשירות 'הגנה על כל החשבונות' והתגובה להן.
ההתראות האלה מזהירות על שינויים משמעותיים בחשבונות Google של המשתמשים, שלרוב יש להם גם השלכות אבטחה על החשבונות שלהם באפליקציה. לדוגמה, אם חשבון Google של משתמש נפרץ, ייתכן שהדבר יוביל לפריצה לחשבון של המשתמש באפליקציה באמצעות שחזור החשבון באימייל או שימוש בכניסה יחידה.
כדי לעזור לכם לצמצם את הסיכון של אירועים כאלה, Google שולחת את אובייקטי השירות שלכם שנקראים אסימוני אירועי אבטחה. האסימונים האלה חושפים מעט מאוד מידע – רק את סוג אירוע האבטחה, מתי הוא התרחש ומזהה המשתמש שהושפע ממנו – אבל אפשר להשתמש בהם כדי לבצע פעולה מתאימה בתגובה. לדוגמה, אם חשבון Google של משתמש נפרץ, תוכלו להשבית באופן זמני את הכניסה באמצעות חשבון Google של המשתמש הזה ולמנוע שליחת הודעות אימייל לשחזור החשבון לכתובת Gmail של המשתמש.
ההגנה על כל החשבונות מבוססת על תקן RISC שפותח ב-OpenID Foundation.
סקירה כללית
כדי להשתמש בהגנה על כל החשבונות באפליקציה או בשירות, צריך להשלים את המשימות הבאות:
מגדירים את הפרויקט ב- .
יוצרים נקודת קצה לקבלת אירועים, שאליה Google תשלח אסימונים של אירועי אבטחה. נקודת הקצה הזו אחראית לאימות האסימונים שהיא מקבלת, ולאחר מכן לתגובה לאירועי אבטחה בכל דרך שתרצו.
כדי להתחיל לקבל אסימונים של אירועי אבטחה, צריך לרשום את נקודת הקצה ב-Google.
דרישות מוקדמות
אתם מקבלים אסימונים של אירועי אבטחה רק ממשתמשי Google שנתתם לשירות הרשאה לגשת לפרטי הפרופיל או לכתובות האימייל שלהם. כדי לקבל את ההרשאה הזו, צריך לבקש את ההיקפים profile
או email
. חבילות ה-SDK החדשות יותר של כניסה באמצעות חשבון Google או חבילות ה-SDK הקודמות של כניסה לחשבון Google מבקשות את ההיקפים האלה כברירת מחדל, אבל אם אתם לא משתמשים בהגדרות ברירת המחדל או אם אתם ניגשים ישירות לנקודת הקצה של OpenID Connect של Google, חשוב לוודא שאתם מבקשים לפחות אחד מההיקפים האלה.
הגדרת פרויקט ב-
כדי להתחיל לקבל אסימונים של אירועי אבטחה, צריך ליצור חשבון שירות ולהפעיל את RISC API בפרויקט . עליכם להשתמש באותו פרויקט שבו אתם משתמשים כדי לגשת לשירותי Google, כמו כניסה באמצעות חשבון Google, באפליקציה.
כדי ליצור את חשבון השירות:
פותחים את . כשמוצגת בקשה, בוחרים את הפרויקטשבו משתמשים כדי לגשת לשירותי Google באפליקציה.
לוחצים על Create credentials > Service account.
יוצרים חשבון שירות חדש עם התפקיד 'אדמין של הגדרות RISC' (
roles/riscconfigs.admin
) לפי ההוראות האלה.יוצרים מפתח לחשבון השירות החדש שנוצר. בוחרים את סוג המפתח של ה-JSON ולוחצים על Create. כשיוצרים את המפתח, מורידים קובץ JSON שמכיל את פרטי הכניסה של חשבון השירות. חשוב לשמור את הקובץ הזה במקום בטוח, אבל גם נגיש לנקודת הקצה של מקבל האירועים.
בדף פרטי הכניסה של הפרויקט, כדאי גם לשים לב למזהי הלקוח שבהם אתם משתמשים כדי להיכנס באמצעות חשבון Google או כדי להיכנס לחשבון Google (מדור קודם). בדרך כלל, יש לכם מזהה לקוח לכל פלטפורמה שאתם תומכים בה. מזהי הלקוח האלה נדרשים כדי לאמת אסימונים של אירועי אבטחה, כפי שמתואר בקטע הבא.
כדי להפעיל את RISC API:
פותחים את דף ה-RISC API ב-. מוודאים שהפרויקט שבו אתם משתמשים כדי לגשת לשירותי Google עדיין מסומן.
קוראים את התנאים של RISC ומוודאים שהם מובנים לכם.
אם אתם מפעילים את ה-API בפרויקט שבבעלות ארגון, עליכם לוודא שיש לכם הרשאה לשייך את הארגון שלכם לתנאי 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
היא מחרוזת שמזהה אירוע אבטחה יחיד, והיא ייחודית למקור הנתונים. אפשר להשתמש במזהה הזה כדי לעקוב אחרי אירועי האבטחה שקיבלת.
הצהרת 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. קריאה ל-API של הגדרת מקור הנתונים של RISC
עכשיו, כשיש לכם אסימון הרשאה, תוכלו להשתמש ב-RISC API כדי להגדיר את מקור האירועים של האבטחה בפרויקט, כולל רישום נקודת הקצה של המכשיר המקבל.
לשם כך, שולחים בקשת POST ב-HTTPS אל 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
כדי לקבל את הגדרות הסטרימינג הנוכחיות, לשנות את גוף התגובה ולשלוח את ההגדרות ששונו ב-POST חזרה אל https://risc.googleapis.com/v1beta/stream:update
, כפי שמתואר למעלה.
איך מפסיקים וממשיכים את מקור האירועים
אם תצטרכו להפסיק את מקור האירועים מ-Google, תוכלו לשלוח בקשת POST מורשית אל https://risc.googleapis.com/v1beta/stream/status:update
עם הערך { "status": "disabled" }
בגוף הבקשה. כשהסטרימינג מושבת, Google לא שולחת אירועים לנקודת הקצה שלכם ולא מאחסנת ב-buffer אירועי אבטחה כשהם מתרחשים. כדי להפעיל מחדש את מקור האירועים, שולחים POST עם הערך { "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. | צריכה להיות כבר הגדרת RISC בפרויקט שלכם ב-Google Cloud. אם אתם משתמשים ב-Firebase והפעלתם את הכניסה באמצעות חשבון Google, מערכת Firebase מנהלת את RISC בפרויקט שלכם. לא תוכלו ליצור הגדרה מותאמת אישית. אם אתם לא משתמשים בכניסה באמצעות חשבון Google בפרויקט Firebase, צריך להשבית אותה ולנסות לעדכן שוב אחרי שעה. |
403 | לא ניתן היה למצוא את הפרויקט. | חשוב לוודא שאתם משתמשים בחשבון השירות הנכון לפרויקט הנכון. יכול להיות שאתם משתמשים בחשבון שירות שמשויך לפרויקט שנמחק. איך רואים את כל חשבונות השירות שמשויכים לפרויקט |
403 | לחשבון השירות צריכה להיות הרשאה לגשת להגדרות RISC | עוברים אל ומקצים את התפקיד 'אדמין של הגדרות RISC' (roles/riscconfigs.admin ) לחשבון השירות שמבצע את הקריאות לפרויקט, לפי ההוראות האלה.
|
403 | רק חשבון שירות יכול לקרוא לממשקי ה-API לניהול של שידורים. | איך קוראים לממשקי Google API באמצעות חשבון שירות |
403 | נקודת הקצה להעברה לא שייכת לאף אחד מהדומיינים של הפרויקט. | לכל פרויקט יש קבוצה של דומיינים מורשים. אם נקודת הקצה של העברת הנתונים (כלומר נקודת הקצה שאליה אתם מצפים שהאירועים של RISC יישלחו) לא מתארחת באף אחד מהם, עליכם להוסיף את הדומיין של נקודת הקצה לקבוצה הזו. |
403 | כדי להשתמש ב-API הזה, צריך להגדיר לפחות לקוח OAuth אחד בפרויקט. | RISC פועל רק אם אתם מפתחים אפליקציה שתומכת בכניסה באמצעות חשבון Google. החיבור הזה מחייב לקוח OAuth. אם אין בפרויקט לקוחות OAuth, סביר להניח ש-RISC לא יעזור לכם. מידע נוסף על השימוש של Google ב-OAuth בממשקי ה-API שלנו |
403 |
סטטוס לא נתמך. סטטוס לא חוקי. |
בשלב הזה אנחנו תומכים רק בסטטוסים enabled ו-disabled של הסטרימינג. |
404 |
לפרויקט אין הגדרת RISC. אין הגדרת RISC קיימת בפרויקט, לא ניתן לעדכן את הסטטוס. |
קוראים לנקודת הקצה https://risc.googleapis.com/v1beta/stream:update כדי ליצור הגדרות חדשות של שידור. |
4XX/5XX | לא ניתן לעדכן את הסטטוס. | מידע נוסף זמין בהודעת השגיאה המפורטת. |
היקפי אסימוני גישה
אם תחליטו להשתמש באסימוני גישה לאימות ב-RISC API, אלה ההיקפים שהאפליקציה שלכם צריכה לבקש:
נקודת קצה (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.