'सभी खातों की सुरक्षा' सुविधा की मदद से उपयोगकर्ता खातों को सुरक्षित रखना

अगर आपका ऐप्लिकेशन उपयोगकर्ताओं को Google का इस्तेमाल करके उनके खातों में साइन इन करने की अनुमति देता है, तो आपके पास इन शेयर किए गए उपयोगकर्ताओं के खातों की सुरक्षा को बेहतर बनाने का विकल्प होता है. इसके लिए, 'सभी खातों की सुरक्षा' सेवा से मिलने वाली सुरक्षा से जुड़ी गतिविधियों की सूचनाएं सुनें और उनका जवाब दें.

ये सूचनाएं आपको आपके उपयोगकर्ताओं के Google खातों में होने वाले बड़े बदलावों के बारे में चेतावनी देती हैं, जिससे अक्सर आपके ऐप्लिकेशन से जुड़े उनके खातों की सुरक्षा पर असर पड़ सकता है. उदाहरण के लिए, अगर किसी उपयोगकर्ता का Google खाता हाइजैक कर लिया जाता है, तो इससे ईमेल खाता वापस पाने या सिंगल साइन-ऑन के ज़रिए आपके ऐप्लिकेशन से उपयोगकर्ता का खाता हैक किया जा सकता है.

इस तरह के इवेंट के जोखिम को कम करने में आपकी मदद करने के लिए, Google आपकी सेवा से जुड़े ऑब्जेक्ट भेजता है. इन ऑब्जेक्ट को सुरक्षा इवेंट टोकन कहा जाता है. इन टोकन से बहुत कम जानकारी मिलती है. जैसे, सिर्फ़ सुरक्षा से जुड़ी गतिविधि का टाइप, इवेंट कब हुआ, और उस उपयोगकर्ता की पहचान क्या होती है. उदाहरण के लिए, अगर किसी उपयोगकर्ता के Google खाते के साथ छेड़छाड़ की गई है, तो उस उपयोगकर्ता के लिए'Google से साइन इन करें' सुविधा को कुछ समय के लिए बंद किया जा सकता है. साथ ही, खाता वापस पाने के ईमेल को उपयोगकर्ता के Gmail पते पर भेजे जाने से रोका जा सकता है.

'सभी खातों की सुरक्षा' सुविधा OpenID Foundation में बनाए गए आरआईएससी स्टैंडर्ड पर आधारित है.

खास जानकारी

अपने ऐप्लिकेशन या सेवा के साथ 'सभी खातों की सुरक्षा' सुविधा का इस्तेमाल करने के लिए, आपको ये टास्क पूरे करने होंगे:

  1. API Consoleमें अपना प्रोजेक्ट सेट अप करें.

  2. इवेंट रिसीवर का एंडपॉइंट बनाएं, जिस पर Google सुरक्षा से जुड़े इवेंट टोकन भेजेगा. यह एंडपॉइंट उसे मिलने वाले टोकन की पुष्टि करने और फिर आपके चुने गए तरीके से सुरक्षा से जुड़ी गतिविधियों के लिए काम करने के लिए ज़िम्मेदार है.

  3. सुरक्षा से जुड़े इवेंट के टोकन पाने के लिए, अपने एंडपॉइंट को Google के साथ रजिस्टर करें.

पहले से आवश्यक

आपको सिर्फ़ उन Google उपयोगकर्ताओं के लिए सुरक्षा इवेंट टोकन मिलते हैं जिन्होंने आपकी सेवा को अपनी प्रोफ़ाइल जानकारी या ईमेल पते ऐक्सेस करने की अनुमति दी है. आपको यह अनुमति, profile या email दायरों का अनुरोध करने पर मिलती है. नया 'Google से साइन इन करें' या लेगसी Google साइन-इन SDK टूल डिफ़ॉल्ट रूप से, इन दायरों का अनुरोध करते हैं. हालांकि, अगर डिफ़ॉल्ट सेटिंग का इस्तेमाल नहीं किया जाता है या अगर आपने सीधे Google के OpenID Connect एंडपॉइंट को ऐक्सेस किया है, तो पक्का करें कि आपने इनमें से कम से कम एक स्कोप के लिए अनुरोध किया हो.

API Consoleमें प्रोजेक्ट सेट अप करें

सुरक्षा से जुड़े इवेंट के टोकन पाने से पहले, आपको सेवा खाता बनाना होगा और अपनेAPI Console प्रोजेक्ट में RISC एपीआई चालू करना होगा. आपको उसी API Console प्रोजेक्ट का इस्तेमाल करना होगा जिसका इस्तेमाल Google की सेवाओं, जैसे कि Google साइन-इन को ऐक्सेस करने के लिए किया जाता है.

सेवा खाता बनाने के लिए:

  1. API Console Credentials page खोलें. जब कहा जाए, तब वह API Console प्रोजेक्ट चुनें जिसका इस्तेमाल, अपने ऐप्लिकेशन में Google की सेवाएं ऐक्सेस करने के लिए किया जाता है.

  2. क्रेडेंशियल बनाएं > सेवा खाता पर क्लिक करें.

  3. आरआईएससी कॉन्फ़िगरेशन एडमिन की भूमिका (roles/riscconfigs.admin) के साथ नया सेवा खाता बनाने के लिए इन निर्देशों का पालन करें.

  4. बनाए गए नए सेवा खाते के लिए कुंजी बनाएं. JSON कुंजी का टाइप चुनें और फिर बनाएं पर क्लिक करें. कुंजी बनाए जाने के बाद, आपको एक JSON फ़ाइल डाउनलोड करनी होगी, जिसमें आपके सेवा खाते के क्रेडेंशियल शामिल होंगे. इस फ़ाइल को किसी सुरक्षित जगह पर रखें, लेकिन इसे आपके इवेंट रिसीवर के एंडपॉइंट से भी ऐक्सेस किया जा सकता है.

प्रोजेक्ट के क्रेडेंशियल वाले पेज पर रहते हुए, उन क्लाइंट आईडी का ध्यान रखें जिनका इस्तेमाल 'Google से साइन इन करें' या 'Google साइन इन' (लेगसी) के लिए किया जाता है. आम तौर पर, आपके पास हर उस प्लैटफ़ॉर्म के लिए एक क्लाइंट आईडी होता है जिस पर आपका ऐप्लिकेशन काम करता है. जैसा कि अगले सेक्शन में बताया गया है, सुरक्षा से जुड़े इवेंट टोकन की पुष्टि करने के लिए आपको इन क्लाइंट आईडी की ज़रूरत होगी.

RISC एपीआई को चालू करने के लिए:

  1. API Consoleमें जाकर RISC API पेज खोलें. पक्का करें कि आप Google की सेवाएं ऐक्सेस करने के लिए जिस प्रोजेक्ट का इस्तेमाल करते हैं उसे अब भी चुना गया हो.

  2. आरआईएससी की शर्तें पढ़ें और पक्का करें कि आपने ज़रूरी शर्तों को समझ लिया है.

    अगर किसी संगठन के मालिकाना हक वाले प्रोजेक्ट के लिए एपीआई चालू किया जा रहा है, तो पक्का करें कि आपके पास आरआईएससी की शर्तों का पालन करने के लिए संगठन को बाध्य करने का अधिकार है.

  3. चालू करें पर सिर्फ़ तब क्लिक करें, जब आप आरआईएससी की शर्तों से सहमत हों.

इवेंट रिसीवर का एंडपॉइंट बनाना

Google से सुरक्षा से जुड़ी गतिविधियों की सूचनाएं पाने के लिए, आपको ऐसा एचटीटीपीएस एंडपॉइंट बनाना होगा जो एचटीटीपीएस पोस्ट अनुरोधों को मैनेज करता हो. इस एंडपॉइंट को रजिस्टर करने के बाद (नीचे देखें), Google, क्रिप्टोग्राफ़िक तरीके से साइन की गई ऐसी स्ट्रिंग पोस्ट करना शुरू करेगा जिन्हें सुरक्षा इवेंट टोकन कहा जाता है. सुरक्षा इवेंट टोकन, हस्ताक्षर किए गए JWT होते हैं. इनमें सुरक्षा से जुड़े किसी एक इवेंट के बारे में जानकारी होती है.

अपने एंडपॉइंट पर मिलने वाले हर सुरक्षा इवेंट टोकन के लिए, सबसे पहले टोकन की पुष्टि करें और उसे डिकोड करें. इसके बाद, अपनी सेवा के मुताबिक सुरक्षा इवेंट को सही तरीके से मैनेज करें. बुरे मकसद से काम करने वाले लोगों या ग्रुप के बुरे हमलों को रोकने के लिए, डिकोड करने से पहले इवेंट टोकन की पुष्टि करना ज़रूरी है. इन सेक्शन में इन कामों के बारे में बताया गया है:

1. सुरक्षा से जुड़ी गतिविधि के टोकन को डिकोड करना और उनकी पुष्टि करना

सिक्योरिटी इवेंट टोकन एक खास तरह का JWT है. इसलिए, इन्हें डिकोड करने और पुष्टि करने के लिए, किसी भी JWT लाइब्रेरी का इस्तेमाल किया जा सकता है. जैसे, jwt.io पर दी गई लाइब्रेरी. आप चाहे किसी भी लाइब्रेरी का इस्तेमाल करें, आपके टोकन की पुष्टि करने वाले कोड को ये काम करने होंगे:

  1. Google के आरआईएससी कॉन्फ़िगरेशन दस्तावेज़ से, 'क्रॉस-खाता सुरक्षा जारी करने वाले' का आइडेंटिफ़ायर (issuer) और साइनिंग पासकोड का सर्टिफ़िकेट यूआरआई (jwks_uri) पाएं. यह दस्तावेज़ आपको https://accounts.google.com/.well-known/risc-configuration पर मिलेगा.
  2. अपनी पसंद की JWT लाइब्रेरी का इस्तेमाल करके, सुरक्षा इवेंट टोकन के हेडर से साइनिंग पासकोड आईडी पाएं.
  3. Google के साइनिंग पासकोड सर्टिफ़िकेट वाले दस्तावेज़ से, पिछले चरण में मिले कुंजी आईडी की मदद से सार्वजनिक पासकोड पाएं. अगर दस्तावेज़ में आपकी पसंदीदा आईडी वाली कुंजी नहीं है, तो हो सकता है कि सुरक्षा से जुड़ी गतिविधि का टोकन अमान्य हो. साथ ही, आपके एंडपॉइंट में एचटीटीपी गड़बड़ी 400 दिखे.
  4. अपनी पसंद की JWT लाइब्रेरी का इस्तेमाल करके, इन बातों की पुष्टि करें:
    • सुरक्षा इवेंट के टोकन को उस सार्वजनिक कुंजी का इस्तेमाल करके साइन किया जाता है जो आपको पिछले चरण में मिली थी.
    • टोकन का aud दावा, आपके ऐप्लिकेशन के क्लाइंट आईडी में से एक है.
    • टोकन का iss दावा, उस जारी करने वाले के आइडेंटिफ़ायर से मेल खाता है जो आपको आरआईएससी के खोजे गए दस्तावेज़ से मिला है. ध्यान दें कि आपको टोकन के खत्म होने (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)

अगर टोकन मान्य है और उसे डिकोड किया गया था, तो एचटीटीपी स्टेटस 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) में है जो नई साइन इन विद Google (Javascript, एचटीएमएल) लाइब्रेरी, लेगसी Google साइन इन लाइब्रेरी या OpenID Connect से जारी किए गए JWT आईडी टोकन में मौजूद है. अगर दावे का 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

ज़रूरी है: अगर खाता बंद करने की वजह 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 API का इस्तेमाल करके, अपने रिसीवर का एंडपॉइंट रजिस्टर करें. RISC एपीआई को किए जाने वाले कॉल के साथ, अनुमति वाला टोकन होना ज़रूरी है.

आपको सुरक्षा से जुड़े इवेंट सिर्फ़ आपके ऐप्लिकेशन के उपयोगकर्ताओं के लिए मिलेंगे. इसलिए, नीचे बताए गए चरण को पूरा करने के लिए, आपके GCP प्रोजेक्ट में OAuth के लिए सहमति वाली स्क्रीन को कॉन्फ़िगर करना होगा.

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 API कॉल करना जारी रखने के लिए, नया टोकन जनरेट करें.

2. RISC स्ट्रीम कॉन्फ़िगरेशन एपीआई को कॉल करें

अब आपके पास अनुमति वाला टोकन है, इसलिए अपने प्रोजेक्ट की सुरक्षा से जुड़ी गतिविधियों की स्ट्रीम को कॉन्फ़िगर करने के लिए RISC API का इस्तेमाल किया जा सकता है. इसमें, रिसीवर को रजिस्टर करने का तरीका भी शामिल है.

ऐसा करने के लिए, 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'])

अगर अनुरोध एचटीटीपी 200 दिखाता है, तो इवेंट स्ट्रीम कॉन्फ़िगर हो गई है. साथ ही, आपके रिसीवर एंडपॉइंट को सुरक्षा से जुड़ी गतिविधि के टोकन मिलने शुरू हो जाने चाहिए. अगले सेक्शन में बताया गया है कि अपनी स्ट्रीम के कॉन्फ़िगरेशन और एंडपॉइंट की जांच कैसे की जा सकती है, ताकि यह पक्का किया जा सके कि सब कुछ एक साथ ठीक से काम कर रहा है.

मौजूदा स्ट्रीम कॉन्फ़िगरेशन को पाना और उसे अपडेट करना

अगर आने वाले समय में, आपको कभी भी अपने स्ट्रीम कॉन्फ़िगरेशन में बदलाव करना हो, तो इसके लिए https://risc.googleapis.com/v1beta/stream को अनुमति मिली हुई GET अनुरोध भेजकर, मौजूदा स्ट्रीम कॉन्फ़िगरेशन पाने, रिस्पॉन्स के मुख्य हिस्से में बदलाव करने, और फिर ऊपर बताए गए तरीके से, बदले गए कॉन्फ़िगरेशन को https://risc.googleapis.com/v1beta/stream:update में वापस पोस्ट करने का विकल्प मिलेगा.

इवेंट स्ट्रीम को रोकना और फिर से शुरू करना

अगर आपको कभी भी Google से इवेंट स्ट्रीम को रोकना हो, तो अनुरोध के मुख्य हिस्से में { "status": "disabled" } का इस्तेमाल करके, https://risc.googleapis.com/v1beta/stream/status:update पर पोस्ट करने का आधिकारिक अनुरोध करें. स्ट्रीम बंद होने पर, Google आपके एंडपॉइंट पर इवेंट नहीं भेजता है. साथ ही, सुरक्षा से जुड़ी गतिविधियों के होने पर उन्हें बफ़र नहीं करता है. इवेंट स्ट्रीम को फिर से चालू करने के लिए, { "status": "enabled" } को उसी एंडपॉइंट पर पोस्ट करें.

3. ज़रूरी नहीं: अपने स्ट्रीम कॉन्फ़िगरेशन की जांच करना

अपनी इवेंट स्ट्रीम के ज़रिए पुष्टि टोकन भेजकर, यह पुष्टि की जा सकती है कि आपका स्ट्रीम कॉन्फ़िगरेशन और रिसीवर एंडपॉइंट एक साथ सही तरीके से काम कर रहे हैं. इस टोकन में एक यूनीक स्ट्रिंग हो सकती है. इसका इस्तेमाल, यह पुष्टि करने के लिए किया जा सकता है कि आपके एंडपॉइंट पर टोकन मिला है या नहीं. इस फ़्लो का इस्तेमाल करने के लिए, पक्का करें कि रिसीवर को रजिस्टर करते समय, https://schemas.openid.net/secevent/risc/event-type/verification इवेंट टाइप की सदस्यता ली जाए.

पुष्टि के टोकन का अनुरोध करने के लिए, https://risc.googleapis.com/v1beta/stream:verify पर आधिकारिक एचटीटीपीएस POST अनुरोध करें. अनुरोध के मुख्य हिस्से में, पहचान करने वाली कुछ स्ट्रिंग बताएं:

{
  "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 डिलीवरी एंडपॉइंट, एचटीटीपीएस यूआरएल होना चाहिए. आपका डिलीवरी एंडपॉइंट (यानी वह एंडपॉइंट जिस पर आप आरआईएससी इवेंट डिलीवर करना चाहते हैं) एचटीटीपीएस होना चाहिए. हम एचटीटीपी यूआरएल को आरआईएससी इवेंट नहीं भेजते.
403 मौजूदा स्ट्रीम कॉन्फ़िगरेशन में आरआईएससी के लिए डिलीवरी का तरीका, निर्देशों का पालन नहीं करता है. आपके Google Cloud प्रोजेक्ट में पहले से ही आरआईएससी कॉन्फ़िगरेशन होना चाहिए. अगर आप Firebase का इस्तेमाल कर रहे हैं और 'Google साइन-इन' चालू है, तो Firebase आपके प्रोजेक्ट के लिए RISC को मैनेज करेगा. पसंद के मुताबिक कॉन्फ़िगरेशन नहीं बनाया जा सकेगा. अगर आपने Firebase प्रोजेक्ट के लिए 'Google साइन इन' का इस्तेमाल नहीं किया है, तो कृपया इसे बंद करें और एक घंटे बाद फिर से अपडेट करने की कोशिश करें.
403 प्रोजेक्ट नहीं मिला. पक्का करें कि आपने सही प्रोजेक्ट के लिए, सही सेवा खाते का इस्तेमाल किया हो. शायद आप मिटाए गए प्रोजेक्ट से जुड़े सेवा खाते का इस्तेमाल कर रहे हैं. किसी किसी प्रोजेक्ट से जुड़े सभी सेवा खातों को देखने का तरीका जानें.
403 सेवा खाते को आपका RISC कॉन्फ़िगरेशन ऐक्सेस करने के लिए अनुमति चाहिए अपने प्रोजेक्ट के API Console पर जाएं और "आरआईएससी कॉन्फ़िगरेशन एडमिन" की भूमिका (roles/riscconfigs.admin) उस सेवा खाते को असाइन करें जो आपके प्रोजेक्ट को इन निर्देशों का पालन करके कॉल कर रहा है.
403 स्ट्रीम मैनेजमेंट एपीआई को सिर्फ़ सेवा खाते से कॉल किया जाना चाहिए. किसी सेवा खाते से Google API को कॉल करने का तरीका यहां ज़्यादा जानें.
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 पर #SecEvent टैग के साथ पोस्ट करें.