כשעובדים עם Azure Java SDK, אנחנו רגילים להתחבר לסביבות הענן השונות בצורה די ישירה: אנחנו בוחרים את הסביבה המתאימה (לדוגמה, Azure Global, Azure China או Azure Government), ומצפים שה-SDK ינהל עבורנו את ההתחברות בצורה שקופה ופשוטה. אבל מה קורה כשזה לא בדיוק עובד ככה? בפוסט זה נסקור בעיה מעניינת שנתקלנו בה בתופין, בהקשר להתחברות לסביבות Azure שונות באמצעות Java, ונראה כיצד פתרנו אותה.
מהן סביבות Azure China ו-Azure GOV?
Azure מציעה מספר סביבות ייחודיות המיועדות לקהלים ספציפיים.
Azure China היא סביבה מבודדת המיועדת לשוק הסיני, מנוהלת על ידי שותף מקומי ופועלת תחת תקנות ורגולציות מקומיות של סין.
לעומתה, Azure Government מיועדת למשרדי ממשלה וללקוחות ארגוניים בארה"ב שדורשים רמות אבטחה גבוהות במיוחד ועמידה בתקנים מחמירים, כגון FedRAMP ו-DOD.
האתגר בהתחברות לסביבות Azure מיוחדות
באחד הפרויקטים שלנו, נדרשנו לתמוך בהתחברות לסביבות שונות של Azure, וביניהן Azure China ו-Azure Government.
באופן טבעי השתמשנו ב-Azure SDK for Java, וניסינו להגדיר את הסביבה המבוקשת בעזרת AzureEnvironment
.
להפתעתנו, למרות ההגדרות, הניסיון לקבל token נכשל שוב ושוב. החיבור ניסה תמיד לשלוח את הבקשה אל ה-URL הכללי והידוע: https://login.microsoftonline.com
, למרות שהגדרנו בבירור סביבות שונות כמו AZURE_CHINA
או AZURE_US_GOVERNMENT
.
לאחר מספר ניסיונות הבנו את מקור הבעיה: למרות שהשתמשנו ב-AzureEnvironment
הנכון, לא הגדרנו נכון את נקודת הגישה (Authority Endpoint) מול שירות ההזדהות של Azure AD.
בעצם, Azure SDK זקוק באופן מפורש להגדרה נכונה של ה-Authority כאשר יוצרים את אובייקט ההזדהות (TokenCredential
). אם לא מעבירים במפורש את הפרמטר הזה, הספרייה תשתמש בברירת המחדל, שהיא Azure Global.
הנה דוגמה לבעיה בקוד המקורי שלנו:
AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE_CHINA);
TokenCredential credential = new ClientSecretCredentialBuilder()
.clientId(clientId)
.clientSecret(clientSecret)
.tenantId(tenantId)
.build();
הקוד הזה נראה לכאורה תקין, אבל הוא למעשה לא מספיק כדי להתחבר נכון לסביבות Azure שאינן גלובליות.
הפתרון: הגדרת מפורשת של Authority Endpoint
הפתרון היה פשוט למדי, אך דורש מודעות לאופן שבו עובד ה-SDK של Azure Java:
AzureProfile profile = new AzureProfile(tenantId, subscriptionId, AzureEnvironment.AZURE_CHINA);
TokenCredential credential = new ClientSecretCredentialBuilder()
.authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint())
.clientId(clientId)
.clientSecret(clientSecret)
.tenantId(tenantId)
.build();
על ידי הגדרת ה-authorityHost
באמצעות profile.getEnvironment().getActiveDirectoryEndpoint()
פתרנו את הבעיה, ואפשרנו לספרייה לפנות לנקודת ההתחברות הנכונה.
זהו בדיוק השלב שרבים מפספסים, כיוון שהתיעוד והדוגמאות הזמינות ברשת נוטים תמיד להניח סביבה גלובלית כברירת מחדל.
סיכום
אם אתם עובדים עם סביבות Azure שונות ב-Java, תמיד ודאו שאתם מעבירים את Authority Endpoint המדויק ל-TokenCredential
שלכם. פעולה זו תמנע תקלות בלתי צפויות ותסייע לכם לחסוך זמן יקר במהלך פיתוח ו-debugging.