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

1. מבוא

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

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

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

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

מה תפַתחו

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

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

מה תלמדו

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

מה צריך להכין

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

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

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

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

הפעלת המסוף ו-Cloud Shell

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

כל הפקודות ב-Codelab הזה יבוצעו ב-Cloud Shell בפרויקט שנוצר ונפתח עבורך. לוחצים על הסמל Activate 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. היא משתמשת ב-framework של Flask כדי להשיב לבקשות אינטרנט עם תוכן של תבנית. קובץ התבנית הזה הוא ב-templates/index.html, ובשלב הזה הוא מכיל רק HTML פשוט. קובץ תבנית נוסף מכיל דוגמה בסיסית למדיניות פרטיות ב-templates/privacy.html.

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

תוכלו להציג כל קובץ במעטפת באמצעות פקודת 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, לוחצים על סמל התפריט בפינה הימנית העליונה של הדף, לוחצים על 'אבטחה' ואז על 'שרת proxy לאימות זהויות (IAP)'.

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

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

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

שם אפליקציה

דוגמה ל-IAP

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

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

דומיין מורשה

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • פותחים את דפדפן האינטרנט בכתובת דף הבית ומוסיפים את הסימן /_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 Standard ל-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, לוחצים על סמל התפריט בפינה הימנית העליונה של הדף, לוחצים על 'אבטחה' ואז על 'שרת 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>

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

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

אם קיים סיכון שהפעולה IAP תושבת או תעקוף אותה, האפליקציה תוכל לבדוק ולוודא שפרטי הזהות שהיא מקבלת תקינים. הפעולה הזו משתמשת בכותרת שלישית של בקשת אינטרנט שנוספה על ידי 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 אפשר להציג את האפליקציה. מזינים את הפקודה הזו. אם לא נפתחת כרטיסייה חדשה בדפדפן, מעתיקים את הקישור שמוצג ופותחים אותו בכרטיסייה חדשה כרגיל.

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

8ef2abcc23d96958.png

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

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

בחלון של מסוף Cloud, לוחצים על סמל התפריט בפינה הימנית העליונה של הדף, לוחצים על 'אבטחה' ואז על 'שרת 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 אימתתם טענות נכונות (assertions) של זהות המשתמש עם חתימה קריפטוגרפית, ולא ניתן לזייף אותן.

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

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