אירוח דף כניסה באמצעות Cloud Run

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

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

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

מגבלות בדף הכניסה

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

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

לפני שמתחילים

  • מפעילים את Compute Engine API.

    הפעלת Compute Engine API

  • במהלך ההגדרה, מסמנים את האפשרות הפעלת זהויות חיצוניות ובוחרים באפשרות יצירת דף כניסה בשבילי. כך Cloud Run ו-FirebaseUI יכולים ליצור בשבילכם דף כניסה.

  • מוודאים שלחשבון השירות שבו נעשה שימוש ב-Cloud Run, ‏ PROJECT_NUMBER-compute@developer.gserviceaccount.com, יש את התפקידים המוגדרים מראש הבאים:

    • roles/identitytoolkit.viewer
    • roles/iap.settingsAdmin
    • roles/compute.networkViewer

הגדרת כתובת ה-URI המורשית להפניה אוטומטית לספקי Identity Platform

אם אתם משתמשים בספקים של Identity Platform שדורשים הפניה אוטומטית לכניסה (הפניה אוטומטית לדף הכניסה של ספק הזהויות החיצוני). צריך להוסיף את כתובת ה-URL של דף הכניסה המתארח ככתובת URL מורשית להפניה אוטומטית בהגדרות של הספק.

לדוגמה, אם הספק הוא Google, צריך לבצע את הפעולות הבאות:

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

  2. נכנסים לדף Credentials במסוף Google Cloud .

    לדף Credentials

  3. מוסיפים את LOGIN_URL/__/auth/handler כאחת מכתובות ה-URI המורשות להפניה אוטומטית של לקוח OAuth 2.0 של האפליקציה. בוחרים את אותו מזהה לקוח ב-OAuth שבו השתמשתם כשקבעתם את ההגדרות של ספק Google.

בספקי SAML ו-OIDC אחרים, מוסיפים את LOGIN_URL/__/auth/handler ככתובת ה-URI המורשית להפניה או ככתובת ה-URL של ACS.

בדיקת דף הכניסה

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

  1. עוברים למשאב שמוגן על ידי IAP. המערכת אמורה להפנות אתכם אוטומטית לדף הכניסה.

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

  3. נכנסים לחשבון באמצעות פרטי הכניסה.

המערכת אמורה להפנות אתכם למשאב המוגן.

התאמה אישית של דף הכניסה

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

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

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

קבלת אסימון גישה

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

  1. נכנסים לדף Identity Platform Providers במסוףGoogle Cloud .

    עוברים לדף Identity Platform Providers

  2. לוחצים על הוספת ספק.

  3. בוחרים באפשרות Google מרשימת הספקים.

  4. מגדירים את מזהה לקוח האינטרנט ואת סוד לקוח האינטרנט:

    1. נכנסים לדף Credentials במסוף Google Cloud .

      לדף Credentials

    2. משתמשים בלקוח OAuth 2.0 קיים או יוצרים לקוח חדש. מגדירים את Client ID ואת Client secret לערכים מזהה לקוח בדפדפן ו-סוד לקוח בדפדפן. מוסיפים את LOGIN_URL/__/auth/handler כאחת מכתובות ה-URI המורשות להפניה אוטומטית עבור לקוח OAuth 2.0. ‫LOGIN_URL היא כתובת ה-URL להתחברות שנוצרה על ידי IAP אחרי שבחרתם באפשרות יצירת דף כניסה בשבילי. אפשר למצוא אותו בדף IAP במסוף Google Cloud , אחרי שבוחרים את המשאב שמאובטח באמצעות IAP.

  5. לוחצים על שמירה בשני הדפים.

כניסה לחלונית הניהול

הגדרות ה-JSON של חלונית LOGIN_URL/admin לדף הכניסה שמתארח ב-Cloud Run. כדי לגשת לחלונית: שימו לב שצריך את התפקיד Storage Admin (אדמין של אחסון) (roles/storage.admin).

  1. נכנסים לדף IAP במסוף Google Cloud .

    כניסה לדף IAP

  2. בוחרים את המשאב מהרשימה.

  3. מפעילים את כתובת ה-URL שמופיעה בקטע התאמה אישית של הדף בחלונית המידע. הוא אמור להיראות כך: https://servicename-xyz-uc.a.run.app/admin.

  4. נכנסים לאותו חשבון Google שבו השתמשתם כדי להגדיר את IAP. מופיע כלי לעריכת טקסט שמכיל את קובץ ההגדרות של JSON.

שינוי ההגדרה

סכימת ההגדרה של דף הכניסה מבוססת על FirebaseUI, והיא יורשת הרבה מהמאפיינים שלה. במקום להשתמש ב-IAP שנוצר LOGIN_URL כ-authDomain שמוגדר כברירת מחדל, אפשר להשתמש ב-PROJECT_ID.firebaseapp.com.

אם רוצים להשתמש ב-PROJECT_ID.firebaseapp.com כ-authDomain, צריך לשנות את signInFlow ל-popup כדי להימנע מבעיה בגישה לאחסון של צד שלישי בדפדפנים מובילים(ראו שיטות מומלצות לשימוש ב-signInWithRedirect בדפדפנים שחוסמים גישה לאחסון של צד שלישי). בנוסף, פועלים לפי ההוראות במאמר הגדרת כתובת URI מורשית להפניה אוטומטית לספקי Identity Platform כדי להוסיף את PROJECT_ID.firebaseapp.com/__/auth/handler כאחת מכתובות ה-URI המורשות להפניה אוטומטית או כתובות ה-URL של ACS לספק Identity Platform שדרכו המשתמשים ייכנסו.

בדוגמה הבאה אפשר לראות הגדרה עם שלושה דיירים:

{
  "AIzaSyC5DtmRUR...": {
    "authDomain": "awesomeco.firebaseapp.com",
    "displayMode": "optionFirst",
    "selectTenantUiTitle": "Awesome Company Portal",
    "selectTenantUiLogo": "https://awesome.com/abcd/logo.png",
    "styleUrl": "https://awesome.com/abcd/overrides/stylesheet.css",
    "tosUrl": "https://awesome.com/abcd/tos.html",
    "privacyPolicyUrl": "https://awesome.com/abcd/privacypolicy.html",
    "tenants": {
      "tenant-a-id": {
        "fullLabel": "Company A Portal",
        "displayName": "Company A",
        "iconUrl": "https://companya.com/img/icon.png",
        "logoUrl": "https://companya.com/img/logo.png",
        "buttonColor": "#007bff",
        "signInFlow": "popup",
        "signInOptions": [
          {
            "provider": "password",
            "requireDisplayName": false,
            "disableSignUp": {
              "status": true,
              "adminEmail": "admin@example.com",
              "helpLink": "https://www.example.com/trouble_signing_in"
            }
          },
          "facebook.com",
          "google.com",
          "microsoft.com",
          {
            "provider": "saml.okta-cicp-app",
            "providerName": "Corp Account",
            "fullLabel": "Employee Corporate Login",
            "buttonColor": "#ff0000",
            "iconUrl": "https://companya.com/abcd/icon-1.png"
          },
          {
            "provider": "oidc.okta-oidc",
            "providerName": "Contractor Account",
            "fullLabel": "Contractor Account Portal",
            "buttonColor": "#00ff00",
            "iconUrl": "https://companya.com/abcd/icon-2.png"
          }
        ],
        "tosUrl": "https://companya.com/abcd/tos.html",
        "privacyPolicyUrl": "https://companya.com/abcd/privacypolicy.html"
      },
      "tenant-b-id": {
        "fullLabel": "Company B Portal",
        "displayName": "Company B",
        "iconUrl": "https://companyb.com/img/icon.png",
        "logoUrl": "https://companyb.com/img/logo.png",
        "buttonColor": "#007bff",
        "immediateFederatedRedirect": true,
        "signInFlow": "popup",
        "signInOptions": [
          {
            "provider": "saml.okta-bla-app",
            "providerName": "Corp Account",
            "buttonColor": "#0000ff",
            "iconUrl": "https://companyb.com/abcd/icon.png"
          }
        ],
        "tosUrl": "https://companyb.com/abcd/tos.html",
        "privacyPolicyUrl": "https://companyb.com/abcd/privacypolicy.html"
      },
      "tenant-c-id": {
        "fullLabel": "Company C Portal",
        "displayName": "Company C",
        "iconUrl": "https://companyc.com/img/icon.png",
        "logoUrl": "https://companyc.com/img/logo.png",
        "buttonColor": "#007bff",
        "immediateFederatedRedirect": true,
        "signInFlow": "popup",
        "signInOptions": [
          {
            "provider": "password",
            "requireDisplayName": false
          },
          {
            "provider": "google.com",
            "scopes": ["scope1", "scope2", "https://example.com/scope3"],
            "loginHintKey": "login_hint",
            "customParameters": {
              "prompt": "consent",
            },
          }
        ],
        "tosUrl": "https://companyc.com/abcd/tos.html",
        "privacyPolicyUrl": "https://companyc.com/abcd/privacypolicy.html",
        "adminRestrictedOperation": {
          "status": true,
          "adminEmail": "admin@example.com",
          "helpLink": "https://www.example.com/trouble_signing_in"
        }
      },
    }
  }
}

רשימה מלאה של המאפיינים הזמינים מופיעה במאמרי העזרה.

שינוי הגדרות CSS

אפשר להשתמש במאפיין styleUrl כדי לציין קובץ CSS בהתאמה אישית. הסגנונות בקובץ הזה יבטלו את ברירת המחדל של CSS. הקובץ צריך להיות נגיש לכולם באמצעות HTTPS (לדוגמה, אם הוא מתארח בקטגוריה של Cloud Storage).

בדוגמה הבאה מוצגת דריסה של ה-CSS שמוגדר כברירת מחדל:

/** Change header title style. */
.heading-center {
  color: #7181a5;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 20px;
  font-weight: bold;
}

/** Use round edged borders for container. */
.main-container {
  border-radius: 5px;
}

/** Change page background color. */
body {
  background-color: #e6eaf0;
}

פריסה מחדש של מופע Cloud Run

במקרים מסוימים, כדאי לפרוס מחדש את מכונת Cloud Run שמארחת את דף הכניסה. תרחישים לדוגמה:

  • הוספה, שינוי או הסרה של ספקי זהויות
  • שינוי הגדרות של דיירים
  • הגדרת משתני סביבה
  • עדכון קובץ האימג' של הקונטיינר לגרסה העדכנית

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

אפשר לקבל את הגרסה הנוכחית של מאגר התגים שפרסו באמצעות נקודת הקצה /versionz. לדוגמה:

curl 'https://servicename-xyz-uc.a.run.app/versionz'

כדי לפרוס מחדש את מכונת Cloud Run:

  1. נכנסים לדף Cloud Run במסוף Google Cloud .

    כניסה לדף Cloud Run

  2. בוחרים את המופע שמארח את דף הכניסה.

  3. לוחצים על עריכה ופריסה של גרסה חדשה.

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

  5. לוחצים על פריסה.

אפשרויות מתקדמות

התאמה אישית של דף הכניסה באופן פרוגרמטי

בנוסף לשימוש במסוף /admin, אפשר לעדכן את הגדרות ה-JSON באופן פרוגרמטי.

כדי לקבל את ההגדרה הנוכחית, משתמשים בנקודת הקצה /get_admin_config. לדוגמה:

curl -H 'Authorization: Bearer [TOKEN]'
  'https://servicename-xyz-uc.a.run.app/get_admin_config'

כדי לעדכן את ההגדרה, משתמשים ב-/set_admin_config. לדוגמה:

curl -XPOST -H 'Authorization: Bearer [TOKEN]' -H "Content-type: application/json"
  -d '[UPDATED-CONFIG]' 'https://servicename-xyz-uc.a.run.app/set_admin_config'

שתי קריאות ה-REST מחייבות את היקף ההרשאות https://www.googleapis.com/auth/devstorage.read_write, ואסימון OAuth תקין צריך להיות מצורף לכותרת Authorization.

הגדרת משתני סביבה

אתם יכולים להגדיר משתני סביבה במופע של Cloud Run כדי להתאים אישית הגדרות מתקדמות. בטבלה הבאה מפורטים המשתנים הזמינים:

משתנה תיאור
DEBUG_CONSOLE ערך בוליאני (0 או 1) שמציין אם לתעד את כל השגיאות והפרטים של בקשות לאחזור מהרשת. מידע אישי רגיש לא יתועד. מושבתת (0) כברירת מחדל.
UI_CONFIG מחרוזת שמכילה את הגדרות ה-JSON של דף הכניסה. השימוש במשתנה הזה במקום בחלונית /admin מאפשר להימנע מקריאה וכתיבה ב-Cloud Storage כשניגשים להגדרה. המערכת מתעלמת מהגדרות לא תקינות. כדי לצמצם את הסיכון לשגיאות תחביר, מומלץ להשתמש בחלונית /admin כדי לאמת את קובץ ה-JSON לפני שמגדירים את המשתנה הזה.
GCS_BUCKET_NAME מחרוזת שמבטלת את קטגוריית ברירת המחדל של Cloud Storage שמשמשת לאחסון הגדרות ה-JSON. שם הקובץ הוא config.json, ומיקום ברירת המחדל הוא gcip-iap-bucket-[CLOUD-RUN-SERVICE-NAME]-[PROJECT-NUMBER].
ALLOW_ADMIN ערך בוליאני (0 או 1) שמציין אם לאפשר גישה לחלונית ההגדרות של /admin. מופעלת (1) כברירת מחדל.

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

התאמה אישית של הדומיין

כברירת מחדל, המשתמשים יראו את כתובת ה-URL של מופע Cloud Run כשהם נכנסים לחשבון. כדי לציין דומיין מותאם אישית במקום זאת:

  1. פועלים לפי השלבים במאמר מיפוי דומיינים בהתאמה אישית כדי להגדיר דומיין בהתאמה אישית למופע של Cloud Run.

  2. מגדירים את IAP לשימוש בכתובת ה-URL החדשה לאימות:

    1. נכנסים לדף IAP במסוף Google Cloud .

      כניסה לדף IAP

    2. בוחרים את המשאב שמוגן על ידי IAP.

    3. בחלונית הצד, לוחצים על סמל העריכה לצד השדה כתובת URL לכניסה.

    4. בוחרים באפשרות שימוש בדף כניסה קיים שמתארח ובוחרים את הדומיין מהתפריט הנפתח.

    5. לוחצים על Save.

שימוש בדף כניסה אחד לכמה משאבי IAP

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

כדי להשתמש שוב בדף כניסה:

  1. פועלים לפי השלבים במאמר הזה כדי לפרוס את דף האימות למשאב הראשון שמוגן על ידי IAP.

  2. מפעילים את IAP למשאב השני. כשמופיעה בקשה לציין דף כניסה, בוחרים באפשרות I'll provide my own ומזינים את כתובת ה-URL של שירות Cloud Run בתור URL.

  3. פורסים מחדש את שירות Cloud Run.

פתרון בעיות

השירות לא זמין בדף כניסה מאוחסן

כשמשתמשים בדף כניסה מתארח, מופיעה השגיאה הבאה:

Service unavailable

לאחר מכן לא תהיה לכם גישה לדף הכניסה.

כדי לפתור את השגיאה, מבצעים את הפעולות הבאות:

  1. מוודאים שקטגוריית ברירת המחדל של Cloud Storage היא בפורמט gcip-iap-bucket-CLOUD_RUN_SERVICE_NAME-PROJECT-NUMBER.

  2. מוודאים שקטגוריית ברירת המחדל של Cloud Storage קיימת ומכילה קובץ בשם config.json.

קובצי Cookie של צד שלישי וחלוקת האחסון למחיצות בדפדפנים

יכול להיות שדף הכניסה או הדף admin/ לא יפעלו כמו שצריך בדפדפנים שבהם קובצי Cookie של צד שלישי מושבתים או שמוטמעת בהם חלוקת האחסון למחיצות. כדי לפתור את הבעיה:

  1. פורסים מחדש את דף הכניסה כדי להשתמש בגרסה העדכנית 1.0.1.

  2. אם התאמתם אישית את דף הכניסה, ודאו שהערך authDomain מוגדר כ-LOGIN_URL שנוצר על ידי IAP. לחלופין, אם הערך של signInFlow הוא popup, אפשר להגדיר את authDomain לערך PROJECT_ID.firebaseapp.com.

    בקטע הקוד הבא מוצגת ההגדרה של authDomain לדף כניסה בהתאמה אישית:

    {
      "AIzaSyC5DtmRUR...": {
        "authDomain": "LOGIN_URL",
        ...
      }
    }
    

    בקטע הקוד הבא מתואר authDomain לדף כניסה popup:

    {
      "AIzaSyC5DtmRUR...": {
        "authDomain": "PROJECT_ID.firebaseapp.com",
        "tenants": {
          "tenant-a-id": {
            ...
            "signInFlow": "popup"
            ...
          }
        }
        ...
      }
    }
    

המאמרים הבאים