যদি আপনার অ্যাপ ব্যবহারকারীদের গুগল ব্যবহার করে তাদের অ্যাকাউন্টে সাইন ইন করার সুযোগ দেয়, তাহলে আপনি ক্রস-অ্যাকাউন্ট প্রোটেকশন সার্ভিসের দেওয়া সিকিউরিটি ইভেন্ট নোটিফিকেশনগুলো শুনে এবং সে অনুযায়ী ব্যবস্থা নেওয়ার মাধ্যমে এই শেয়ার করা ব্যবহারকারীদের অ্যাকাউন্টের নিরাপত্তা উন্নত করতে পারেন।
এই নোটিফিকেশনগুলো আপনার ব্যবহারকারীদের গুগল অ্যাকাউন্টের বড় ধরনের পরিবর্তন সম্পর্কে আপনাকে সতর্ক করে, যা প্রায়শই আপনার অ্যাপে থাকা তাদের অ্যাকাউন্টের নিরাপত্তার জন্যও ঝুঁকিপূর্ণ হতে পারে। উদাহরণস্বরূপ, যদি কোনো ব্যবহারকারীর গুগল অ্যাকাউন্ট হ্যাক হয়ে যায়, তাহলে ইমেল অ্যাকাউন্ট রিকভারি বা সিঙ্গেল সাইন-অন ব্যবহারের মাধ্যমে আপনার অ্যাপে থাকা তার অ্যাকাউন্টটি ঝুঁকির মুখে পড়তে পারে।
এই ধরনের ঘটনার ঝুঁকি কমাতে আপনাকে সাহায্য করার জন্য, গুগল আপনার সার্ভিস অবজেক্ট পাঠায়, যেগুলোকে সিকিউরিটি ইভেন্ট টোকেন বলা হয়। এই টোকেনগুলো খুব সামান্য তথ্য প্রকাশ করে—শুধু নিরাপত্তা ঘটনার ধরন ও কখন এটি ঘটেছে, এবং ক্ষতিগ্রস্ত ব্যবহারকারীর শনাক্তকারী—কিন্তু আপনি এর প্রতিক্রিয়ায় যথাযথ ব্যবস্থা নিতে এগুলো ব্যবহার করতে পারেন। উদাহরণস্বরূপ, যদি কোনো ব্যবহারকারীর গুগল অ্যাকাউন্ট হ্যাক হয়, তাহলে আপনি সাময়িকভাবে সেই ব্যবহারকারীর জন্য ‘সাইন ইন উইথ গুগল’ নিষ্ক্রিয় করে দিতে পারেন এবং ব্যবহারকারীর জিমেইল ঠিকানায় অ্যাকাউন্ট পুনরুদ্ধারের ইমেল পাঠানো বন্ধ করতে পারেন।
ক্রস-অ্যাকাউন্ট সুরক্ষা ওপেনআইডি ফাউন্ডেশনে বিকশিত RISC স্ট্যান্ডার্ডের উপর ভিত্তি করে তৈরি।
সংক্ষিপ্ত বিবরণ
আপনার অ্যাপ বা পরিষেবার সাথে ক্রস-অ্যাকাউন্ট প্রোটেকশন ব্যবহার করতে হলে, আপনাকে নিম্নলিখিত কাজগুলো সম্পন্ন করতে হবে:
এপিআই কনসোলে আপনার প্রজেক্টটি সেট আপ করুন।
একটি ইভেন্ট রিসিভার এন্ডপয়েন্ট তৈরি করুন, যেখানে গুগল সিকিউরিটি ইভেন্ট টোকেন পাঠাবে। এই এন্ডপয়েন্টটি প্রাপ্ত টোকেনগুলো যাচাই করার এবং তারপর আপনার পছন্দের যেকোনো উপায়ে সিকিউরিটি ইভেন্টগুলোতে সাড়া দেওয়ার জন্য দায়ী থাকবে।
নিরাপত্তা ইভেন্ট টোকেন পেতে শুরু করার জন্য আপনার এন্ডপয়েন্টটি গুগলের সাথে নিবন্ধন করুন।
পূর্বশর্ত
আপনি শুধুমাত্র সেইসব গুগল ব্যবহারকারীদের জন্য সিকিউরিটি ইভেন্ট টোকেন পাবেন, যারা আপনার পরিষেবাটিকে তাদের প্রোফাইল তথ্য বা ইমেল ঠিকানা অ্যাক্সেস করার অনুমতি দিয়েছেন। profile বা email স্কোপের জন্য অনুরোধ করার মাধ্যমে আপনি এই অনুমতিটি পান। নতুন 'সাইন ইন উইথ গুগল' বা পুরোনো 'গুগল সাইন-ইন' SDK-গুলো ডিফল্টরূপে এই স্কোপগুলোর জন্য অনুরোধ করে, কিন্তু আপনি যদি ডিফল্ট সেটিংস ব্যবহার না করেন, অথবা যদি সরাসরি গুগলের ওপেনআইডি কানেক্ট এন্ডপয়েন্ট অ্যাক্সেস করেন, তবে নিশ্চিত করুন যে আপনি এই স্কোপগুলোর মধ্যে অন্তত একটির জন্য অনুরোধ করছেন।
এপিআই কনসোলে একটি প্রজেক্ট সেট আপ করুন
সিকিউরিটি ইভেন্ট টোকেন গ্রহণ করা শুরু করার আগে, আপনাকে অবশ্যই একটি সার্ভিস অ্যাকাউন্ট তৈরি করতে হবে এবং আপনার এপিআই কনসোল প্রজেক্টে RISC API সক্রিয় করতে হবে। আপনার অ্যাপে গুগল সাইন-ইন-এর মতো গুগল পরিষেবাগুলো অ্যাক্সেস করার জন্য আপনি যে এপিআই কনসোল প্রজেক্টটি ব্যবহার করেন, আপনাকে অবশ্যই সেই একই প্রজেক্টটি ব্যবহার করতে হবে।
সার্ভিস অ্যাকাউন্ট তৈরি করতে:
এপিআই কনসোল ক্রেডেনশিয়ালস পৃষ্ঠাটি খুলুন। অনুরোধ করা হলে, আপনার অ্যাপে গুগল পরিষেবাগুলো অ্যাক্সেস করতে ব্যবহৃত এপিআই কনসোল প্রজেক্টটি বেছে নিন।
ক্রেডেনশিয়াল তৈরি করুন > পরিষেবা অ্যাকাউন্ট-এ ক্লিক করুন।
এই নির্দেশাবলী অনুসরণ করে RISC Configuration Admin রোল (
roles/riscconfigs.admin) সহ একটি নতুন সার্ভিস অ্যাকাউন্ট তৈরি করুন।আপনার নতুন তৈরি করা সার্ভিস অ্যাকাউন্টের জন্য একটি কী (key) তৈরি করুন। JSON কী টাইপটি বেছে নিন এবং তারপর 'Create' এ ক্লিক করুন। কী-টি তৈরি হয়ে গেলে, আপনি একটি JSON ফাইল ডাউনলোড করবেন, যেটিতে আপনার সার্ভিস অ্যাকাউন্টের ক্রেডেনশিয়াল থাকবে। এই ফাইলটি একটি নিরাপদ স্থানে রাখুন, তবে এটি যেন আপনার ইভেন্ট রিসিভার এন্ডপয়েন্টের কাছেও অ্যাক্সেসযোগ্য থাকে।
আপনার প্রোজেক্টের ক্রেডেনশিয়ালস পেজে থাকাকালীন, সাইন ইন উইথ গুগল বা গুগল সাইন-ইন (লেগ্যাসি)-এর জন্য ব্যবহৃত ক্লায়েন্ট আইডিগুলোও নোট করে নিন। সাধারণত, আপনার সাপোর্ট করা প্রতিটি প্ল্যাটফর্মের জন্য একটি করে ক্লায়েন্ট আইডি থাকে। পরবর্তী বিভাগে বর্ণিত সিকিউরিটি ইভেন্ট টোকেনগুলো ভ্যালিডেট করার জন্য আপনার এই ক্লায়েন্ট আইডিগুলোর প্রয়োজন হবে।
RISC API সক্রিয় করতে:
এপিআই কনসোলে RISC API পৃষ্ঠাটি খুলুন। নিশ্চিত করুন যে আপনি গুগল পরিষেবাগুলি অ্যাক্সেস করতে যে প্রজেক্টটি ব্যবহার করেন সেটি এখনও নির্বাচিত আছে।
RISC-এর শর্তাবলী পড়ুন এবং এর প্রয়োজনীয়তাগুলো বুঝতে পেরেছেন কিনা তা নিশ্চিত করুন।
আপনি যদি কোনো প্রতিষ্ঠানের মালিকানাধীন প্রকল্পের জন্য এপিআই (API) সক্রিয় করেন, তাহলে নিশ্চিত করুন যে আপনি আপনার প্রতিষ্ঠানকে RISC শর্তাবলীর সাথে আবদ্ধ করার জন্য অনুমোদিত।
আপনি যদি RISC শর্তাবলীতে সম্মত হন তবেই সক্ষম করুন -এ ক্লিক করুন।
একটি ইভেন্ট রিসিভার এন্ডপয়েন্ট তৈরি করুন
গুগল থেকে নিরাপত্তা ইভেন্টের বিজ্ঞপ্তি পেতে, আপনাকে একটি HTTPS এন্ডপয়েন্ট তৈরি করতে হবে যা HTTPS POST অনুরোধগুলি পরিচালনা করে। এই এন্ডপয়েন্টটি নিবন্ধন করার পরে (নীচে দেখুন), গুগল এন্ডপয়েন্টটিতে নিরাপত্তা ইভেন্ট টোকেন নামক ক্রিপ্টোগ্রাফিকভাবে স্বাক্ষরিত স্ট্রিং পোস্ট করা শুরু করবে। নিরাপত্তা ইভেন্ট টোকেনগুলি হল স্বাক্ষরিত JWT যা একটি একক নিরাপত্তা-সম্পর্কিত ইভেন্টের তথ্য ধারণ করে।
আপনার এন্ডপয়েন্টে প্রাপ্ত প্রতিটি সিকিউরিটি ইভেন্ট টোকেনের জন্য, প্রথমে টোকেনটি যাচাই ও ডিকোড করুন, তারপর আপনার পরিষেবার জন্য যথাযথভাবে সিকিউরিটি ইভেন্টটি পরিচালনা করুন। দুষ্কৃতকারীদের ক্ষতিকারক আক্রমণ প্রতিরোধ করার জন্য ডিকোড করার আগে ইভেন্ট টোকেনটি যাচাই করা অপরিহার্য । নিম্নলিখিত বিভাগগুলিতে এই কাজগুলি বর্ণনা করা হয়েছে:
১. নিরাপত্তা ইভেন্ট টোকেনটি ডিকোড এবং যাচাই করুন
যেহেতু সিকিউরিটি ইভেন্ট টোকেনগুলো এক বিশেষ ধরনের JWT, তাই আপনি এগুলো ডিকোড ও ভ্যালিডেট করার জন্য jwt.io- তে তালিকাভুক্ত যেকোনো JWT লাইব্রেরি ব্যবহার করতে পারেন। আপনি যে লাইব্রেরিই ব্যবহার করুন না কেন, আপনার টোকেন ভ্যালিডেশন কোডকে অবশ্যই নিম্নলিখিত কাজগুলো করতে হবে:
- গুগলের RISC কনফিগারেশন ডকুমেন্ট থেকে ক্রস-অ্যাকাউন্ট প্রোটেকশন ইস্যুকারী আইডেন্টিফায়ার (
issuer) এবং সাইনিং কী সার্টিফিকেট URI (jwks_uri) সংগ্রহ করুন, যা আপনিhttps://accounts.google.com/.well-known/risc-configuration- এই ঠিকানায় পাবেন। - আপনার পছন্দের JWT লাইব্রেরি ব্যবহার করে, সিকিউরিটি ইভেন্ট টোকেনের হেডার থেকে সাইনিং কী আইডিটি সংগ্রহ করুন।
- গুগলের সাইনিং কী সার্টিফিকেট ডকুমেন্ট থেকে, পূর্ববর্তী ধাপে পাওয়া কী আইডি সহ পাবলিক কী-টি সংগ্রহ করুন। যদি ডকুমেন্টটিতে আপনার কাঙ্ক্ষিত আইডি সহ কোনো কী না থাকে, তাহলে সম্ভবত সিকিউরিটি ইভেন্ট টোকেনটি অবৈধ, এবং আপনার এন্ডপয়েন্টে HTTP error 400 রিটার্ন করবে।
- আপনার পছন্দের JWT লাইব্রেরি ব্যবহার করে নিম্নলিখিত বিষয়গুলো যাচাই করুন:
- পূর্ববর্তী ধাপে আপনার পাওয়া পাবলিক কী ব্যবহার করে সিকিউরিটি ইভেন্ট টোকেনটি স্বাক্ষরিত হয়।
- টোকেনটির
audক্লেইম হলো আপনার অ্যাপগুলোর ক্লায়েন্ট আইডিগুলোর মধ্যে একটি। - টোকেনটির
issক্লেইমটি আপনার RISC ডিসকভারি ডকুমেন্ট থেকে পাওয়া ইস্যুকারী আইডেন্টিফায়ারের সাথে মিলে যায়। উল্লেখ্য যে, আপনার টোকেনটির মেয়াদ (exp) যাচাই করার প্রয়োজন নেই, কারণ সিকিউরিটি ইভেন্ট টোকেনগুলো ঐতিহাসিক ঘটনাকে প্রতিনিধিত্ব করে এবং সেহেতু এগুলোর কোনো মেয়াদ শেষ হয় না।
উদাহরণস্বরূপ:
জাভা
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;
}
পাইথন
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 রিটার্ন করুন। এরপর, টোকেন দ্বারা নির্দেশিত সিকিউরিটি ইভেন্টটি হ্যান্ডেল করুন।
২. নিরাপত্তা ইভেন্টগুলি পরিচালনা করুন
ডিকোড করা হলে, একটি সিকিউরিটি ইভেন্ট টোকেন নিচের উদাহরণের মতো দেখায়:
{
"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 ক্লেইমটি একজন নির্দিষ্ট ব্যবহারকারীকে তার অনন্য গুগল অ্যাকাউন্ট আইডি ( sub ) দিয়ে শনাক্ত করে। এই গুগল অ্যাকাউন্ট আইডিটি হলো সেই একই আইডেন্টিফায়ার ( sub ), যা নতুন 'সাইন ইন উইথ গুগল' ( জাভাস্ক্রিপ্ট , এইচটিএমএল ) লাইব্রেরি, পুরোনো গুগল সাইন-ইন লাইব্রেরি, বা ওপেনআইডি কানেক্ট দ্বারা ইস্যু করা JWT আইডি টোকেনগুলোতে থাকে। যখন ক্লেইমটির subject_type id_token_claims হয়, তখন এতে ব্যবহারকারীর ইমেল অ্যাড্রেসসহ একটি email ফিল্ডও অন্তর্ভুক্ত থাকতে পারে।
নির্দিষ্ট ব্যবহারকারীর অ্যাকাউন্টে ইভেন্টের ধরন অনুযায়ী যথাযথ ব্যবস্থা নিতে events ক্লেইমের তথ্য ব্যবহার করুন।
OAuth টোকেন শনাক্তকারী
স্বতন্ত্র টোকেন সম্পর্কিত OAuth ইভেন্টগুলির জন্য, টোকেন সাবজেক্ট আইডেন্টিফায়ার টাইপটিতে নিম্নলিখিত ফিল্ডগুলি থাকে:
token_type: শুধুমাত্রrefresh_tokenসমর্থিত।token_identifier_alg: সম্ভাব্য মানগুলোর জন্য নিচের সারণিটি দেখুন।token: নিচের সারণিটি দেখুন।
| টোকেন_আইডেন্টিফায়ার_অ্যালগ | টোকেন |
|---|---|
prefix | টোকেনটির প্রথম ১৬টি অক্ষর। |
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 | প্রয়োজনীয় : টোকেনটি যদি গুগল সাইন-ইন-এর জন্য হয়, তবে তাদের বর্তমানে চালু থাকা সেশনগুলো বন্ধ করে দিন। এছাড়াও, আপনি ব্যবহারকারীকে একটি বিকল্প সাইন-ইন পদ্ধতি সেট আপ করার পরামর্শ দিতে পারেন। পরামর্শ : টোকেনটি যদি অন্য গুগল এপিআই অ্যাক্সেস করার জন্য হয়, তাহলে ব্যবহারকারীর আপনার কাছে সংরক্ষিত যেকোনো OAuth টোকেন মুছে ফেলুন। | |
https://schemas.openid.net/secevent/oauth/event-type/token-revoked | টোকেন শনাক্তকারীগুলির জন্য OAuth টোকেন শনাক্তকারী বিভাগটি দেখুন। | প্রয়োজনীয় : যদি আপনি সংশ্লিষ্ট রিফ্রেশ টোকেনটি সংরক্ষণ করেন, তবে সেটি মুছে ফেলুন এবং পরবর্তীবার অ্যাক্সেস টোকেনের প্রয়োজন হলে ব্যবহারকারীকে পুনরায় সম্মতি দেওয়ার জন্য অনুরোধ করুন। |
https://schemas.openid.net/secevent/risc/event-type/account-disabled | reason=hijackingreason=bulk-account | প্রয়োজনীয় : যদি পরামর্শ : যদি পরামর্শ : যদি কোনো কারণ উল্লেখ না করা হয়, তবে ব্যবহারকারীর জন্য গুগল সাইন-ইন নিষ্ক্রিয় করুন এবং ব্যবহারকারীর গুগল অ্যাকাউন্টের সাথে যুক্ত ইমেল ঠিকানা (সাধারণত, তবে আবশ্যিকভাবে নয়, একটি জিমেইল অ্যাকাউন্ট) ব্যবহার করে অ্যাকাউন্ট পুনরুদ্ধার নিষ্ক্রিয় করুন। ব্যবহারকারীকে একটি বিকল্প সাইন-ইন পদ্ধতির প্রস্তাব দিন। |
https://schemas.openid.net/secevent/risc/event-type/account-enabled | পরামর্শ : ব্যবহারকারীর জন্য গুগল সাইন-ইন পুনরায় চালু করুন এবং ব্যবহারকারীর গুগল অ্যাকাউন্টের ইমেল ঠিকানা ব্যবহার করে অ্যাকাউন্ট পুনরুদ্ধার পুনরায় চালু করুন। | |
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required | পরামর্শ : আপনার পরিষেবাতে কোনো সন্দেহজনক কার্যকলাপের ওপর নজর রাখুন এবং যথাযথ ব্যবস্থা গ্রহণ করুন। | |
https://schemas.openid.net/secevent/risc/event-type/verification | রাজ্য= state | পরামর্শ : একটি টেস্ট টোকেন পাওয়া গেছে বলে লগ করুন। |
পুনরাবৃত্ত এবং বাদ পড়া ইভেন্টগুলি
ক্রস-অ্যাকাউন্ট প্রোটেকশন সেইসব ইভেন্ট পুনরায় ডেলিভার করার চেষ্টা করবে যেগুলো তার মতে ডেলিভার করা হয়নি। তাই, আপনি মাঝে মাঝে একই ইভেন্ট একাধিকবার পেতে পারেন। যদি এর ফলে বারবার একই কাজ করতে হয় যা আপনার ব্যবহারকারীদের জন্য অসুবিধাজনক, তাহলে ইভেন্টগুলো থেকে ডুপ্লিকেট ইভেন্ট বাদ দেওয়ার জন্য jti ক্লেইম (যা একটি ইভেন্টের জন্য অনন্য শনাক্তকারী) ব্যবহার করার কথা বিবেচনা করুন। গুগল ক্লাউড ডেটাফ্লো-এর মতো কিছু এক্সটার্নাল টুল রয়েছে যা আপনাকে এই ডি-ডুপ ডেটাফ্লো কার্যকর করতে সাহায্য করতে পারে।
মনে রাখবেন যে ইভেন্টগুলো সীমিত সংখ্যক বার চেষ্টার মাধ্যমে ডেলিভারি করা হয়, তাই আপনার রিসিভার দীর্ঘ সময়ের জন্য বন্ধ থাকলে আপনি স্থায়ীভাবে কিছু ইভেন্ট মিস করতে পারেন।
আপনার রিসিভার নিবন্ধন করুন
নিরাপত্তা ইভেন্ট গ্রহণ শুরু করতে, RISC API ব্যবহার করে আপনার রিসিভার এন্ডপয়েন্টটি রেজিস্টার করুন। RISC API-তে করা কলের সাথে অবশ্যই একটি অথরাইজেশন টোকেন থাকতে হবে।
আপনি শুধুমাত্র আপনার অ্যাপের ব্যবহারকারীদের জন্য নিরাপত্তা ইভেন্ট পাবেন, তাই নিচে বর্ণিত ধাপগুলোর পূর্বশর্ত হিসেবে আপনার GCP প্রজেক্টে একটি OAuth কনসেন্ট স্ক্রিন কনফিগার করা থাকতে হবে।
১. একটি অনুমোদন টোকেন তৈরি করুন
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-jwt এবং গুগলের অথোরাইজেশন লাইব্রেরি ব্যবহার করে:
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;
}
পাইথন
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 কল করা চালিয়ে যাওয়ার জন্য একটি নতুন টোকেন তৈরি করুন।
২. RISC স্ট্রিম কনফিগারেশন API-কে কল করুন
এখন যেহেতু আপনার কাছে একটি অথরাইজেশন টোকেন আছে, আপনি RISC API ব্যবহার করে আপনার প্রোজেক্টের সিকিউরিটি ইভেন্ট স্ট্রিম কনফিগার করতে পারেন, যার মধ্যে আপনার রিসিভার এন্ডপয়েন্ট রেজিস্টার করাও অন্তর্ভুক্ত।
এটি করার জন্য, https://risc.googleapis.com/v1beta/stream:update -এ একটি HTTPS POST অনুরোধ পাঠান, এবং আপনার রিসিভার এন্ডপয়েন্ট ও আপনি যে ধরনের নিরাপত্তা ইভেন্টগুলিতে আগ্রহী তা উল্লেখ করুন:
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
]
}
উদাহরণস্বরূপ:
জাভা
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);
পাইথন
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 ফেরত দেয়, তাহলে ইভেন্ট স্ট্রিমটি সফলভাবে কনফিগার করা হয়েছে এবং আপনার রিসিভার এন্ডপয়েন্টটি সিকিউরিটি ইভেন্ট টোকেন গ্রহণ করা শুরু করবে। পরবর্তী বিভাগে বর্ণনা করা হয়েছে কীভাবে আপনি আপনার স্ট্রিম কনফিগারেশন এবং এন্ডপয়েন্ট পরীক্ষা করে যাচাই করতে পারেন যে সবকিছু একসাথে সঠিকভাবে কাজ করছে।
আপনার বর্তমান স্ট্রিম কনফিগারেশনটি সংগ্রহ ও আপডেট করুন।
ভবিষ্যতে যদি আপনি কখনও আপনার স্ট্রিম কনফিগারেশন পরিবর্তন করতে চান, তাহলে উপরে বর্ণিত পদ্ধতি অনুযায়ী বর্তমান স্ট্রিম কনফিগারেশন পাওয়ার জন্য https://risc.googleapis.com/v1beta/stream এ একটি অনুমোদিত GET অনুরোধ পাঠান, রেসপন্স বডি পরিবর্তন করুন এবং তারপর পরিবর্তিত কনফিগারেশনটি https://risc.googleapis.com/v1beta/stream:update এ পুনরায় POST করুন।
ইভেন্ট স্ট্রিমটি থামান এবং পুনরায় চালু করুন।
যদি আপনার কখনো গুগলের ইভেন্ট স্ট্রিম বন্ধ করার প্রয়োজন হয়, তাহলে রিকোয়েস্ট বডিতে { "status": "disabled" } সহ https://risc.googleapis.com/v1beta/stream/status:update এ একটি অনুমোদিত POST রিকোয়েস্ট পাঠান। স্ট্রিমটি নিষ্ক্রিয় থাকা অবস্থায়, গুগল আপনার এন্ডপয়েন্টে কোনো ইভেন্ট পাঠায় না এবং নিরাপত্তা সংক্রান্ত ইভেন্ট ঘটলে তা বাফারও করে না। ইভেন্ট স্ট্রিমটি পুনরায় সক্রিয় করতে, একই এন্ডপয়েন্টে { "status": "enabled" } POST করুন।
৩. ঐচ্ছিক: আপনার স্ট্রিম কনফিগারেশন পরীক্ষা করুন।
আপনার ইভেন্ট স্ট্রিমের মাধ্যমে একটি ভেরিফিকেশন টোকেন পাঠিয়ে আপনি যাচাই করতে পারেন যে আপনার স্ট্রিম কনফিগারেশন এবং রিসিভার এন্ডপয়েন্ট একসাথে সঠিকভাবে কাজ করছে কিনা। এই টোকেনটিতে একটি অনন্য স্ট্রিং থাকতে পারে, যা ব্যবহার করে আপনি যাচাই করতে পারবেন যে টোকেনটি আপনার এন্ডপয়েন্টে গৃহীত হয়েছে। এই ফ্লোটি ব্যবহার করার জন্য, আপনার রিসিভার রেজিস্টার করার সময় https://schemas.openid.net/secevent/risc/event-type/verification ইভেন্ট টাইপটিতে সাবস্ক্রাইব করা নিশ্চিত করুন।
একটি ভেরিফিকেশন টোকেন অনুরোধ করতে, https://risc.googleapis.com/v1beta/stream:verify -এ একটি অনুমোদিত HTTPS POST অনুরোধ পাঠান। অনুরোধের বডিতে, একটি শনাক্তকারী স্ট্রিং উল্লেখ করুন:
{
"state": "ANYTHING"
}
উদাহরণস্বরূপ:
জাভা
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);
পাইথন
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 থেকে নিম্নলিখিত ত্রুটিগুলো ফেরত আসতে পারে:
| ত্রুটি কোড | ত্রুটি বার্তা | প্রস্তাবিত পদক্ষেপ |
|---|---|---|
| ৪০০ | স্ট্রিম কনফিগারেশনে অবশ্যই $fieldname ফিল্ডটি থাকতে হবে। | https://risc.googleapis.com/v1beta/stream:update এন্ডপয়েন্টে আপনার অনুরোধটি অবৈধ অথবা পার্স করা যাচ্ছে না। অনুগ্রহ করে আপনার অনুরোধে $fieldname অন্তর্ভুক্ত করুন। |
| ৪০১ | অননুমোদিত। | অনুমোদন ব্যর্থ হয়েছে। নিশ্চিত করুন যে আপনি অনুরোধের সাথে একটি অনুমোদন টোকেন সংযুক্ত করেছেন এবং টোকেনটি বৈধ ও মেয়াদোত্তীর্ণ নয়। |
| ৪০৩ | ডেলিভারি এন্ডপয়েন্ট অবশ্যই একটি HTTPS URL হতে হবে। | আপনার ডেলিভারি এন্ডপয়েন্ট (অর্থাৎ, যে এন্ডপয়েন্টে RISC ইভেন্টগুলো ডেলিভার হবে বলে আপনি আশা করেন) অবশ্যই HTTPS হতে হবে। আমরা HTTP URL-এ RISC ইভেন্ট পাঠাই না। |
| ৪০৩ | বিদ্যমান স্ট্রিম কনফিগারেশনে RISC-এর জন্য স্পেক-সম্মত ডেলিভারি পদ্ধতি নেই। | আপনার গুগল ক্লাউড প্রজেক্টে আগে থেকেই একটি RISC কনফিগারেশন থাকা আবশ্যক। আপনি যদি ফায়ারবেস ব্যবহার করেন এবং গুগল সাইন-ইন চালু রাখেন, তাহলে ফায়ারবেস আপনার প্রজেক্টের জন্য RISC পরিচালনা করবে; আপনি কোনো কাস্টম কনফিগারেশন তৈরি করতে পারবেন না। আপনি যদি আপনার ফায়ারবেস প্রজেক্টে গুগল সাইন-ইন ব্যবহার না করেন, তবে অনুগ্রহ করে এটি নিষ্ক্রিয় করুন এবং এক ঘণ্টা পর আবার আপডেট করার চেষ্টা করুন। |
| ৪০৩ | প্রকল্পটি খুঁজে পাওয়া যায়নি। | নিশ্চিত করুন যে আপনি সঠিক প্রজেক্টের জন্য সঠিক সার্ভিস অ্যাকাউন্ট ব্যবহার করছেন। হতে পারে আপনি মুছে ফেলা কোনো প্রজেক্টের সাথে যুক্ত একটি সার্ভিস অ্যাকাউন্ট ব্যবহার করছেন। একটি প্রজেক্টের সাথে যুক্ত সমস্ত সার্ভিস অ্যাকাউন্ট কীভাবে দেখতে হয় তা জানুন। |
| ৪০৩ | আপনার RISC কনফিগারেশন অ্যাক্সেস করার জন্য সার্ভিস অ্যাকাউন্টের অনুমতি প্রয়োজন। | এই নির্দেশাবলী অনুসরণ করে আপনার প্রোজেক্টের API কনসোলে যান এবং যে সার্ভিস অ্যাকাউন্টটি আপনার প্রোজেক্টে কল করছে, তাকে "RISC Configuration Admin" রোলটি ( roles/riscconfigs.admin ) প্রদান করুন। |
| ৪০৩ | স্ট্রিম ম্যানেজমেন্ট এপিআইগুলো শুধুমাত্র একটি সার্ভিস অ্যাকাউন্ট থেকেই কল করা উচিত। | একটি সার্ভিস অ্যাকাউন্ট ব্যবহার করে কীভাবে গুগল এপিআই কল করতে পারেন, সে সম্পর্কে এখানে আরও তথ্য দেওয়া হলো। |
| ৪০৩ | ডেলিভারি এন্ডপয়েন্টটি আপনার প্রজেক্টের কোনো ডোমেইনের অন্তর্ভুক্ত নয়। | প্রতিটি প্রজেক্টের একটি অনুমোদিত ডোমেইন সেট থাকে। যদি আপনার ডেলিভারি এন্ডপয়েন্ট (অর্থাৎ, যে এন্ডপয়েন্টে RISC ইভেন্টগুলো ডেলিভার হওয়ার কথা) সেগুলোর কোনোটিতে হোস্ট করা না থাকে, তাহলে আপনাকে এন্ডপয়েন্টটির ডোমেইন সেই সেটে যুক্ত করতে হবে। |
| ৪০৩ | এই এপিআই ব্যবহার করতে হলে আপনার প্রজেক্টে অন্তত একটি OAuth ক্লায়েন্ট কনফিগার করা থাকতে হবে। | RISC শুধুমাত্র তখনই কাজ করে যদি আপনি এমন একটি অ্যাপ তৈরি করেন যা গুগল সাইন ইন সমর্থন করে। এই সংযোগের জন্য একটি OAuth ক্লায়েন্ট প্রয়োজন। যদি আপনার প্রোজেক্টে কোনো OAuth ক্লায়েন্ট না থাকে, তাহলে সম্ভবত RISC আপনার জন্য উপযোগী হবে না। আমাদের API-গুলোর জন্য গুগলের OAuth ব্যবহার সম্পর্কে আরও জানুন। |
| ৪০৩ | অসমর্থিত অবস্থা। অবৈধ অবস্থা। | এই মুহূর্তে আমরা শুধুমাত্র “ enabled ” এবং “ disabled ” স্ট্রিম স্ট্যাটাস সমর্থন করি। |
| ৪০৪ | প্রকল্পটিতে কোনো 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 |
সাহায্য প্রয়োজন?
প্রথমে, আমাদের এরর কোড রেফারেন্স সেকশনটি দেখে নিন। এরপরও যদি আপনার কোনো প্রশ্ন থাকে, তবে #SecEvents ট্যাগ ব্যবহার করে সেগুলো স্ট্যাক ওভারফ্লো-তে পোস্ট করুন।