אימות משתמש באמצעות שרת proxy לאימות זהויות (IAP)

1. מבוא

לעתים קרובות יש צורך באימות משתמשים באפליקציית האינטרנט שלכם, ובדרך כלל נדרש תכנות מיוחד באפליקציה. באפליקציות של Google Cloud Platform, אפשר להעביר את האחריות הזו לשירות שרת proxy לאימות זהויות (IAP). אם אתם רוצים להגביל את הגישה רק למשתמשים נבחרים, לא צריך לבצע שינויים באפליקציה. אם האפליקציה צריכה לדעת את זהות המשתמש (למשל כדי לשמור את העדפות המשתמש בצד השרת), שרת proxy לאימות זהויות יכול לספק את המידע הזה עם מינימום קוד אפליקציה.

מהו שרת proxy לאימות זהויות (IAP)?

שרת proxy לאימות זהויות (IAP) הוא שירות של Google Cloud Platform שמיירט בקשות אינטרנט שנשלחות לאפליקציה שלכם, מאמת את המשתמש ששולח את הבקשה באמצעות שירות הזהויות של Google, ומאפשר לבקשות לעבור רק אם הן מגיעות ממשתמש שנתתם לו הרשאה. בנוסף, הוא יכול לשנות את כותרות הבקשות כדי לכלול מידע על המשתמש המאומת.

ב-Codelab הזה נסביר איך ליצור אפליקציה משלכם, להגביל את הגישה אליה ולקבל את זהות המשתמש מ-IAP.

מה תפַתחו

ב-Codelab הזה תיצרו אפליקציית אינטרנט מינימלית באמצעות Google App Engine, ואז תבדקו דרכים שונות להשתמש ב-Identity-Aware Proxy כדי להגביל את הגישה לאפליקציה ולספק לה פרטי זהות של משתמשים. האפליקציה שלכם:

  • הצגת דף פתיחה
  • גישה לפרטי הזהות של המשתמש שסופקו על ידי IAP
  • שימוש באימות קריפטוגרפי כדי למנוע זיוף של פרטי הזיהוי של המשתמשים

מה תלמדו

  • איך לכתוב ולפרוס אפליקציית App Engine פשוטה באמצעות Python 3.7
  • איך מפעילים ומשביתים IAP כדי להגביל את הגישה לאפליקציה
  • איך מקבלים מידע על זהות המשתמש מ-IAP לאפליקציה
  • איך מאמתים מידע מ-IAP באמצעות הצפנה כדי להגן מפני זיוף

מה תצטרכו

  • דפדפן אינטרנט מודרני כמו Chrome.
  • ידע בסיסי בשפת התכנות Python

ה-Codelab הזה מתמקד ב-Google App Engine וב-IAP. מושגים ובלוקים של קוד שלא רלוונטיים מוצגים בקצרה, ואתם יכולים פשוט להעתיק ולהדביק אותם.

2. תהליך ההגדרה

תעבדו בסביבת שורת הפקודה של Cloud Shell. מתחילים בפתיחת הסביבה הזו ואחזור קוד לדוגמה.

הפעלת Cloud Shell ו-Console

בפינה הימנית העליונה של דף ה-Lab, לוחצים על הלחצן Open Google Console (פתיחת Google Console). תצטרכו להתחבר באמצעות שם המשתמש והסיסמה שמופיעים מתחת לכפתור.

כל הפקודות ב-codelab הזה יבוצעו ב-Cloud Shell עבור הפרויקט שנוצר ונפתח בשבילכם. לוחצים על סמל ההפעלה של Cloud Shell בצד שמאל של הכותרת בדף המסוף כדי לפתוח אותו. בחלק התחתון של הדף אפשר להזין ולהריץ פקודות.אפשר להריץ את הפקודות מהמחשב שלכם, אבל קודם צריך להתקין ולהגדיר את תוכנת הפיתוח הנדרשת. ב-Cloud Shell כבר יש את כל כלי התוכנה שאתם צריכים.

הורדת הקוד

לוחצים על אזור שורת הפקודה ב-Cloud Shell כדי להקליד פקודות. מאחזרים את הקוד מ-Github ואז עוברים לתיקיית הקוד:

git clone https://github.com/googlecodelabs/user-authentication-with-iap.git
cd user-authentication-with-iap

התיקייה הזו מכילה תיקיית משנה אחת לכל שלב ב-Codelab הזה. תעברו לתיקייה הנכונה כדי לבצע כל שלב.

3. שלב 1 – פריסת האפליקציה והגנה עליה באמצעות IAP

זוהי אפליקציה רגילה של App Engine שנכתבה ב-Python 3.7 ומציגה רק דף פתיחה עם הכיתוב Hello, World. אנחנו נבצע פריסה ובדיקה של התכונה, ואז נגביל את הגישה אליה באמצעות IAP.

בדיקת קוד האפליקציה

עוברים מתיקיית הפרויקט הראשית לתיקיית המשנה 1-HelloWorld שמכילה את הקוד של השלב הזה.

cd 1-HelloWorld

קוד האפליקציה נמצא בקובץ main.py. הוא משתמש ב-Flask, מסגרת אינטרנט, כדי להגיב לבקשות אינטרנט עם התוכן של תבנית. קובץ התבנית נמצא ב-templates/index.html, ובשלב הזה הוא מכיל רק HTML פשוט. קובץ תבנית שני מכיל דוגמה של מדיניות פרטיות בסיסית בפורמט templates/privacy.html.

יש עוד שני קבצים: בקובץ requirements.txt מפורטות כל ספריות Python שאינן ברירת מחדל שבהן האפליקציה משתמשת, ובקובץ app.yaml מצוין ל-Google Cloud Platform שזו אפליקציית Python 3.7 App Engine.

אפשר לרשום כל קובץ ב-Shell באמצעות הפקודה cat, כמו בדוגמה הבאה:

cat main.py

לחלופין, אפשר ללחוץ על סמל העיפרון בפינה השמאלית העליונה של חלון Cloud Shell כדי לפתוח את עורך הקוד של Cloud Shell ולבדוק את הקוד.

לא צריך לשנות קבצים בשלב הזה.

פריסה ב-App Engine

עכשיו פורסים את האפליקציה בסביבה הרגילה של App Engine ל-Python 3.7

gcloud app deploy

יכול להיות שתתבקשו לבחור אזור לפריסה. בוחרים באחת מהאפשרויות שקרובות אליכם וכתוב עליהן שהיא 'תומכת בתקן'. כשמוצגת השאלה אם אתם רוצים להמשיך, מזינים Y כדי לאשר.

תוך כמה דקות הפריסה תושלם ותוצג לכם הודעה שאפשר להציג את האפליקציה באמצעות gcloud app browse. מזינים את הפקודה. אם כרטיסייה חדשה לא נפתחת בדפדפן, לוחצים על הקישור שמוצג כדי לפתוח אותו בכרטיסייה חדשה, או מעתיקים אותו לכרטיסייה חדשה שנפתחה באופן ידני, אם צריך. זו הפעם הראשונה שהאפליקציה הזו מופעלת, ולכן ייקח כמה שניות עד שהיא תופיע בזמן שהמופע בענן יופעל, ואז יופיע החלון הבא.

1c1c0b166c6023e.png

אפשר לפתוח את אותה כתובת URL מכל מחשב שמחובר לאינטרנט כדי לראות את דף האינטרנט הזה. הגישה עדיין לא מוגבלת.

הגבלת הגישה באמצעות IAP

בחלון של מסוף Cloud, לוחצים על סמל התפריט בפינה הימנית העליונה של הדף, לוחצים על Security (אבטחה) ואז על שרת proxy לאימות זהויות (IAP).

מכיוון שזו הפעם הראשונה שאתם מפעילים אפשרות אימות לפרויקט הזה, תוצג לכם הודעה שלפיה אתם צריכים להגדיר את מסך ההסכמה ל-OAuth לפני שתוכלו להשתמש ב-IAP.

לוחצים על הלחצן 'הגדרת מסך בקשת ההסכמה'. תיפתח כרטיסייה חדשה שבה תוכלו להגדיר את מסך ההסכמה.

ממלאים את הערכים המתאימים במשבצות הריקות הנדרשות:

שם אפליקציה

דוגמה ל-IAP

כתובת אימייל לתמיכה

כתובת האימייל שלכם. יכול להיות שהיא כבר מולאה בשבילכם.

דומיין מורשה

החלק של שם המארח בכתובת ה-URL של האפליקציה, למשל iap-example-999999.appspot.com. אפשר לראות את זה בסרגל הכתובות של דף האינטרנט Hello World שפתחתם קודם. אל תכללו את התו https:// בתחילת כתובת ה-URL או את התו / בסוף שלה.אחרי שמזינים את הערך הזה, צריך ללחוץ על Enter.

קישור לדף הבית של האפליקציה

כתובת ה-URL שבה השתמשתם כדי להציג את האפליקציה

קישור למדיניות הפרטיות של האפליקציה

הקישור לדף הפרטיות באפליקציה, זהה לקישור לדף הבית עם התוספת ‎ /privacy בסוף

לוחצים על שמירה. תוצג בקשה ליצור פרטי כניסה. אין צורך ליצור פרטי כניסה ל-codelab הזה, לכן אפשר פשוט לסגור את כרטיסיית הדפדפן הזו.

חוזרים לדף של שרת proxy לאימות זהויות (IAP) ומרעננים אותו. עכשיו אמורה להופיע רשימה של משאבים שאפשר להגן עליהם.לוחצים על לחצן ההפעלה בעמודה IAP בשורה של אפליקציית App Engine כדי להפעיל את IAP.

יוצגו שמות הדומיינים שיוגנו על ידי IAP. לוחצים על 'הפעלה'.

עכשיו פותחים כרטיסייה בדפדפן ועוברים לכתובת ה-URL של האפליקציה. יוצג מסך כניסה באמצעות חשבון Google שבו תצטרכו להתחבר כדי לגשת לאפליקציה.

נכנסים באמצעות חשבון Google או חשבון G Suite. יוצג מסך שבו תידחה הגישה שלכם.

הגנת על האפליקציה באמצעות IAP, אבל עדיין לא ציינת לחשבונות IAP אילו חשבונות לאפשר.

חוזרים לדף Identity-Aware Proxy ב-Console, מסמנים את תיבת הסימון לצד אפליקציית App Engine ורואים את סרגל הצד בצד שמאל של הדף.

צריך להוסיף כחברים את כל כתובות האימייל (או כתובות של קבוצות Google, או שמות דומיין של G Suite) שרוצים לאפשר להן גישה. לוחצים על הוספת חבר. מזינים את כתובת האימייל ובוחרים את תפקיד המשתמש Cloud IAP/IAP-Secured Web App כדי להקצות אותו לכתובת. באותו אופן, אפשר להזין עוד כתובות או דומיינים של G Suite.

לוחצים על 'שמירה'. ההודעה 'המדיניות עודכנה' תופיע בתחתית החלון.

חוזרים לאפליקציה וטוענים מחדש את הדף. עכשיו אמורה להופיע אפליקציית האינטרנט, כי כבר התחברתם באמצעות משתמש שהרשיתם לו גישה. עם זאת, יכול להיות שעדיין תראו את הדף 'אין לך גישה' כי יכול להיות שהרכישה מתוך האפליקציה לא תבדוק מחדש את ההרשאה שלכם. במקרה כזה, צריך לבצע את השלבים הבאים:

  • פותחים את דפדפן האינטרנט לכתובת של דף הבית עם התוספת /_gcp_iap/clear_login_cookie בסוף כתובת ה-URL, כמו בדוגמה https://iap-example-999999.appspot.com/_gcp_iap/clear_login_cookie.
  • יוצג מסך חדש של 'כניסה באמצעות חשבון Google', והחשבון שלכם כבר יופיע בו. לא לוחצים על החשבון. במקום זאת, לוחצים על 'שימוש בחשבון אחר' ומזינים מחדש את פרטי הכניסה.
  • השלבים האלה גורמים ל-IAP לבדוק מחדש את הגישה שלכם, ועכשיו אמור להופיע מסך הבית של האפליקציה.

אם יש לכם גישה לדפדפן אחר או שאתם יכולים להשתמש במצב פרטי בדפדפן שלכם, ויש לכם חשבון תקף אחר ב-Gmail או ב-G Suite, אתם יכולים להשתמש בדפדפן הזה כדי לעבור לדף האפליקציה ולהיכנס באמצעות החשבון האחר. מכיוון שהחשבון הזה לא קיבל הרשאה, במקום האפליקציה שלכם יוצג לו המסך 'אין לך גישה'.

4. שלב 2 – גישה לפרטי הזהות של המשתמש

אחרי שאפליקציה מוגנת באמצעות IAP, היא יכולה להשתמש בפרטי הזהות ש-IAP מספק בכותרות של בקשות האינטרנט שהיא מעבירה. בשלב הזה, האפליקציה תקבל את כתובת האימייל של המשתמש המחובר ומזהה משתמש ייחודי וקבוע שהוקצה למשתמש הזה על ידי שירות הזהויות של Google. הנתונים האלה יוצגו למשתמש בדף הפתיחה.

זהו שלב 2, והשלב האחרון הסתיים כש-Cloud Shell פתוח בתיקייה iap-codelab/1-HelloWorld. עוברים לתיקייה של השלב הזה:

cd ~/iap-codelab/2-HelloUser

פריסה ב-App Engine

הפריסה נמשכת כמה דקות, לכן מתחילים בפריסת האפליקציה לסביבה הרגילה של App Engine ל-Python 3.7:

gcloud app deploy

כשמוצגת השאלה אם אתם רוצים להמשיך, מזינים Y לאישור. הפריסה אמורה להסתיים תוך כמה דקות. בזמן ההמתנה, אפשר לבדוק את קובצי הבקשה כמו שמתואר בהמשך.

כשהפריסה תהיה מוכנה, תופיע הודעה שאפשר להציג את האפליקציה באמצעות gcloud app browse. מזינים את הפקודה. אם לא נפתחת כרטיסייה חדשה בדפדפן, מעתיקים את הקישור שמוצג ופותחים אותו בכרטיסייה חדשה כרגיל. אמור להופיע דף שדומה לזה:

5b5fb03111258cec.png

יכול להיות שתצטרכו להמתין כמה דקות עד שהגרסה החדשה של האפליקציה תחליף את הגרסה הקודמת. אם צריך, מרעננים את הדף כדי לראות דף שדומה לזה שמוצג למעלה.

בדיקת קבצי האפליקציה

התיקייה הזו מכילה את אותה קבוצת קבצים שמופיעה בשלב 1, אבל שניים מהקבצים השתנו: main.py ו-templates/index.html. התוכנית שונתה כך שהיא מאחזרת את פרטי המשתמש ש-IAP מספקת בכותרות הבקשה, והתבנית מציגה עכשיו את הנתונים האלה.

יש שתי שורות בקובץ main.py שמקבלות את נתוני הזהות שסופקו על ידי IAP:

user_email = request.headers.get('X-Goog-Authenticated-User-Email')
user_id = request.headers.get('X-Goog-Authenticated-User-ID')

הכותרות X-Goog-Authenticated-User- מסופקות על ידי IAP, והשמות לא תלויי-רישיות, כך שאפשר לציין אותם באותיות קטנות או גדולות בלבד, אם רוצים. ההצהרה render_template כוללת עכשיו את הערכים האלה כדי שיוצגו:

page = render_template('index.html', email=user_email, id=user_id)

כדי להציג את הערכים האלה בתבנית index.html, צריך להוסיף את השמות בתוך סוגריים מסולסלים כפולים:

Hello, {{ email }}! Your persistent ID is {{ id }}.

כפי שאפשר לראות, הנתונים שסופקו מתחילים בקידומת accounts.google.com:, שמציינת את המקור של המידע. אם רוצים, האפליקציה יכולה להסיר את כל מה שמופיע עד הנקודתיים כולל, כדי לקבל את הערכים הגולמיים.

השבתה של רכישות מתוך האפליקציה

מה קורה לאפליקציה הזו אם IAP מושבת, או אם נעקף בדרך כלשהי (למשל על ידי אפליקציות אחרות שפועלות באותו פרויקט בענן)? כדי לראות את הנתונים, צריך להשבית את האפשרות 'רכישות מתוך האפליקציה'.

בחלון של מסוף Cloud, לוחצים על סמל התפריט בפינה הימנית העליונה של הדף, לוחצים על Security (אבטחה) ואז על שרת proxy לאימות זהויות (IAP). לוחצים על המתג של IAP לצד אפליקציית App Engine כדי להשבית את IAP.

תוצג לכם אזהרה שלפיה כל המשתמשים יוכלו לגשת לאפליקציה.

מרעננים את דף האינטרנט של האפליקציה. אתם אמורים לראות את אותו הדף, אבל ללא פרטי משתמש:

17c850de95fea839.png

מאחר שהאפליקציה לא מוגנת יותר, משתמש יכול לשלוח בקשת אינטרנט שנראית כאילו היא עברה דרך IAP. לדוגמה, אפשר להריץ את פקודת ה-curl הבאה מ-Cloud Shell כדי לעשות זאת (צריך להחליף את <your-url-here> בכתובת ה-URL הנכונה של האפליקציה):

curl -X GET <your-url-here> -H "X-Goog-Authenticated-User-Email: totally fake email"

דף האינטרנט יוצג בשורת הפקודה, ויראה כך:

<!doctype html>
<html>
<head>
  <title>IAP Hello User</title>
</head>
<body>
  <h1>Hello World</h1>

  <p>
    Hello, totally fake email! Your persistent ID is None.
  </p>

  <p>
    This is step 2 of the <em>User Authentication with IAP</em>
    codelab.
 </p>

</body>
</html>

אין דרך לאפליקציה לדעת שרכישות מתוך האפליקציה הושבתו או שעקפו אותן. במקרים שבהם מדובר בסיכון פוטנציאלי, בשלב 3 מוצג פתרון.

5. שלב 3 – שימוש באימות קריפטוגרפי

אם יש סיכון להשבתה או לעקיפה של הרכישות מתוך האפליקציה, האפליקציה יכולה לבדוק כדי לוודא שפרטי הזהות שהיא מקבלת תקפים. הכותרת הזו היא כותרת שלישית של בקשת אינטרנט שנוספה על ידי IAP, והיא נקראת X-Goog-IAP-JWT-Assertion. הערך של הכותרת הוא אובייקט עם חתימה קריפטוגרפית, שמכיל גם את נתוני הזהות של המשתמש. האפליקציה יכולה לאמת את החתימה הדיגיטלית ולהשתמש בנתונים שמופיעים באובייקט הזה כדי לוודא שהם סופקו על ידי IAP ללא שינוי.

אימות חתימה דיגיטלית דורש כמה שלבים נוספים, כמו אחזור של קבוצת המפתחות הציבוריים העדכנית של Google. אתם יכולים להחליט אם האפליקציה שלכם צריכה את השלבים הנוספים האלה בהתאם לסיכון שמישהו יוכל להשבית או לעקוף את הרכישות מתוך האפליקציה, ולרגישות של האפליקציה.

זהו שלב 3, והשלב האחרון הסתיים כש-Cloud Shell פתוח בתיקייה iap-codelab/2-HelloUser. עוברים לתיקייה של השלב הזה:

cd ~/iap-codelab/3-HelloVerifiedUser

פריסה ב-App Engine

פורסים את האפליקציה בסביבה הרגילה של App Engine ל-Python 3.7:

gcloud app deploy

כשמוצגת השאלה אם אתם רוצים להמשיך, מזינים Y לאישור. הפריסה אמורה להסתיים תוך כמה דקות. בזמן ההמתנה, אפשר לבדוק את קובצי הבקשה כמו שמתואר בהמשך.

כשהפריסה תהיה מוכנה, תופיע הודעה שאפשר להציג את האפליקציה באמצעות gcloud app browse. מזינים את הפקודה. אם לא נפתחת כרטיסייה חדשה בדפדפן, מעתיקים את הקישור שמוצג ופותחים אותו בכרטיסייה חדשה כרגיל.

זוכרים שהשבתתם את הרכישות מתוך האפליקציה בשלב 2, ולכן לא מסופקים לאפליקציה נתונים של רכישות מתוך האפליקציה. אמור להופיע דף שדומה לזה:

8ef2abcc23d96958.png

כמו קודם, יכול להיות שתצטרכו להמתין כמה דקות עד שהגרסה החדשה ביותר תהיה פעילה ותוכלו לראות את הגרסה החדשה של הדף.

מכיוון שהתכונה 'רכישות מתוך האפליקציה' מושבתת, אין מידע על המשתמשים. עכשיו מפעילים מחדש את הרכישות מתוך האפליקציה.

בחלון של מסוף Cloud, לוחצים על סמל התפריט בפינה הימנית העליונה של הדף, לוחצים על Security (אבטחה) ואז על שרת proxy לאימות זהויות (IAP). לוחצים על המתג של IAP לצד אפליקציית App Engine כדי להפעיל שוב את IAP.

יש לרענן את הדף. הדף אמור להיראות כך:

3a4d93c11f228852.png

שימו לב שכתובת האימייל שסופקה בשיטת האימות לא כוללת את הקידומת accounts.google.com:.

אם הרכישות מתוך האפליקציה מושבתות או אם נעקפו, הנתונים המאומתים יהיו חסרים או לא תקפים, כי לא יכול להיות להם חתימה תקפה אלא אם הם נוצרו על ידי בעל המפתחות הפרטיים של Google.

בדיקת קבצי האפליקציה

התיקייה הזו מכילה את אותה קבוצת קבצים שמופיעה בשלב 2, עם שני קבצים ששונו וקובץ חדש אחד. הקובץ החדש הוא auth.py, שמספק שיטה של user() לאחזור ולאימות של פרטי הזהות החתומים בצורה מוצפנת. הקבצים ששונו הם main.py ו-templates/index.html, שמשתמשים עכשיו בתוצאות של השיטה הזו. כדי להשוות, מוצגות גם הכותרות שלא אומתו, כפי שנמצאו בשלב 2.

הפונקציונליות החדשה נמצאת בעיקר בפונקציה user():

def user():
    assertion = request.headers.get('X-Goog-IAP-JWT-Assertion')
    if assertion is None:
        return None, None

    info = jwt.decode(
        assertion,
        keys(),
        algorithms=['ES256'],
        audience=audience()
    )

    return info['email'], info['sub']

assertion הוא הנתונים שסופקו בכותרת הבקשה שצוינה, והם חתומים בצורה מוצפנת. הקוד משתמש בספרייה כדי לאמת ולפענח את הנתונים האלה. האימות מתבצע באמצעות המפתחות הציבוריים ש-Google מספקת כדי לבדוק את הנתונים שהיא חותמת עליהם, ולדעת מה הקהל שהנתונים הוכנו עבורו (בעצם, פרויקט בענן של Google Cloud שמוגן). פונקציות העזר keys() ו-audience() אוספות את הערכים האלה ומחזירות אותם.

לאובייקט החתום יש שני חלקי נתונים שאנחנו צריכים: כתובת האימייל המאומתת וערך המזהה הייחודי (שמופיע ב-sub, בשדה הרגיל של המנוי).

כך משלימים את שלב 3.

6. סיכום

הפעלתם אפליקציית אינטרנט ב-App Engine. בשלב 1 הגבלתם את הגישה לאפליקציה רק למשתמשים שבחרתם. בשלב 2, אחזרת והצגת את הזהות של משתמשים שקיבלו גישה לאפליקציה שלך דרך IAP, וראית איך אפשר לזייף את המידע הזה אם IAP מושבת או אם נעקף. בשלב 3, אימתתם טענות חתומות קריפטוגרפית לגבי זהות המשתמש, שלא ניתן לזייף.

7. הסרת המשאבים

המשאבים היחידים ב-Google Cloud Platform שבהם השתמשתם ב-codelab הזה הם מכונות App Engine. בכל פעם שפרסתם את האפליקציה, נוצרה גרסה חדשה שלה, והיא ממשיכה להתקיים עד למחיקה. יוצאים מה-Lab כדי למחוק את הפרויקט ואת כל המשאבים שבו.