שימוש באסימוני OAuth של צד שלישי

אתם צופים במסמכי התיעוד של Apigee Edge.
כדאי לעיין במסמכי התיעוד של Apigee X.
מידע

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

בדרך כלל, Apigee Edge יוצר טוקן OAuth, מאחסן אותו ומחזיר אותו לאפליקציה שקוראת לו. אחר כך האפליקציה ששולחת את הקריאה מציגה את הטוקן הזה בחזרה ל-Apigee Edge כשמבקשים שירות, ו-Apigee Edge – באמצעות מדיניות OAuthV2 עם Operation = VerifyAccessToken – יאמת שהטוקן תקף. במאמר הזה מוסבר איך להגדיר את Apigee Edge כך שיאחסן אסימון OAuth שנוצר במקום אחר, תוך שמירה על אותו חלק של אימות האסימון, בדיוק כמו אם האסימון נוצר על ידי Edge.

דוגמה

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

מה זה?

נניח שיש לכם מערכת הרשאות קיימת, ואתם רוצים להשתמש בערכי האסימון או הקוד שנוצרו על ידי המערכת הזו במקום בערכי האסימון או הקוד של OAuth2 שנוצרו על ידי Edge. לאחר מכן תוכלו לשלוח בקשות מאובטחות של proxy ל-API עם האסימון או הקוד שהוחלפו, ומערכת Edge תאמת אותן כאילו הן נוצרו על ידי Edge.

רקע מסוים

בדרך כלל, Apigee Edge יוצר טוקן על ידי הפקת מחרוזת אקראית של אותיות ומספרים. ‫Apigee Edge משייך לטוקן הזה נתונים אחרים, כמו השעה שבה הטוקן הונפק, תאריך התפוגה, רשימת מוצרי ה-API שהטוקן תקף לגביהם וההיקף. כל המידע הזה יכול לחזור בתגובה שנוצרת באופן אוטומטי על ידי מדיניות OAuthV2 שהוגדרה עם Operation = GenerateAccessToken. התגובה אמורה להיראות כך:

{
  "issued_at": "1469735625687",
  "application_name": "06947a86-919e-4ca3-ac72-036723b18231",
  "scope": "urn://example.com/read",
  "status": "approved",
  "api_product_list": "[implicit-test]",
  "api_product_list_json": ["implicit-test"],
  "expires_in": "1799", //--in seconds
  "developer.email": "joe@weathersample.com",
  "token_type": "BearerToken",
  "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk",
  "access_token": "zBC90HhCGmGlaMBWeZAai2s3za5j",
  "organization_name": "wwitman",
  "refresh_token_expires_in": "0", //--in seconds
  "refresh_count": "0"
}

הערך של המאפיין access_token הוא למעשה מפתח החיפוש של נתוני התגובה. אפליקציה יכולה לשלוח בקשה ל-proxy ל-API שמתארח ב-Edge, עם טוקן למוכ"ז zBC90HhCGmGlaMBWeZAai2s3za5j, ו-Edge – עם מדיניות OAuthV2 עם Operation = VerifyAccessToken – יחפש את הטוקן, יאחזר את כל המידע וישתמש במידע הזה כדי לקבוע אם הטוקן תקף או לא, עבור ה-proxy ל-API המבוקש. הפעולה הזו נקראת אימות אסימון. כל הפרטים שצוינו למעלה מרכיבים את האסימון. הערך של access_token הוא רק הדרך לחפש את המידע הזה.

לעומת זאת, אם תפעלו לפי השלבים שמתוארים כאן, תוכלו להגדיר את Edge כך שיאחסן אסימון שערך access_token שלו הוא ערך שנוצר על ידי שירות חיצוני. יכול להיות שכל שאר המטא-נתונים יהיו זהים. לדוגמה, נניח שיש לכם מערכת חיצונית ל-Apigee Edge שמייצרת טוקנים מהצורה TOKEN-<16 מספרים אקראיים> . במקרה כזה, המטא-נתונים המלאים של הטוקן שמאוחסנים ב-Apigee Edge יכולים להיות:

{
  "issued_at": "1469735625687",
  "application_name": "06947a86-919e-4ca3-ac72-036723b18231",
  "scope": "urn://example.com/read",
  "status": "approved",
  "api_product_list": "[implicit-test]",
  "api_product_list_json": ["implicit-test"],
  "expires_in": "1799", //--in seconds
  "developer.email": "joe@weathersample.com",
  "token_type": "BearerToken",
  "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk",
  "access_token": "TOKEN-1092837373654221",
  "organization_name": "wwitman",
  "refresh_token_expires_in": "0", //--in seconds
  "refresh_count": "0"
}

במקרה כזה, אפליקציה יכולה לשלוח בקשה ל-proxy ל-API שמתארח ב-Edge, עם טוקן ה-bearer TOKEN-1092837373654221, ו-Edge – באמצעות מדיניות OAuthV2 עם Operation = VerifyAccessToken – יוכל לאמת אותו. אפשר להשתמש בדפוס ייבוא דומה גם לקודי הרשאה ולטוקנים לרענון.

עכשיו נדבר על אימות פרטי הכניסה של הלקוח

אחת מהדרישות המוקדמות ליצירת אסימון היא אימות הלקוח ששולח את הבקשה. כברירת מחדל, המדיניות OAuthV2/GenerateAccessToken ב-Apigee Edge מאמתת באופן מרומז את פרטי הכניסה של הלקוח. בדרך כלל, בבקשה לטוקן OAuthV2, הערכים client_id ו-client_secret מועברים בכותרת Authorization, מקודדים באמצעות אימות בסיסי של HTTP (מחוברים באמצעות נקודתיים, ואז מקודדים ב-base64). המדיניות OAuthV2/GenerateAccessToken ב-Apigee Edge מפענחת את הכותרת הזו, מחפשת את client_id ומוודאת ש-client_secret שמועבר תקף עבור client_id הזה. השיטה הזו פועלת אם פרטי הכניסה מוכרים ל-Apigee Edge – כלומר, אם יש אפליקציה למפתחים שמאוחסנת ב-Apigee Edge ומכילה פרטי כניסה, שכוללים את client_id ו-client_secret שצוינו.

אם לא רוצים לאמת את פרטי הכניסה של הלקוח באמצעות Apigee Edge, צריך לתכנן את ה-API Proxy כך שיתבצע אימות מפורש של הלקוח באמצעים אחרים לפני יצירת הטוקן. לרוב זה קורה באמצעות מדיניות ServiceCallout שמתחברת לנקודת קצה מרוחקת ברשת שלכם.

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

אם רוצים שמדיניות OAuthV2/GenerateAccessToken ב-Apigee Edge תאמת את פרטי הכניסה של הלקוח מול חנות Edge, צריך להגדיר את הרכיב <ExternalAuthorization> לערך false בהגדרת המדיניות, או להשמיט אותו לחלוטין. אם רוצים להשתמש בשירות הרשאות חיצוני כדי לאמת במפורש את פרטי הכניסה של הלקוח, צריך להגדיר את <ExternalAuthorization> ל-true.

יכול להיות ש-Apigee Edge לא יאמת את פרטי הכניסה של הלקוח, אבל עדיין צריך ש-Apigee Edge יכיר את client_id וינהל אותו. כל access_token ב-Apigee Edge, בין אם הוא נוצר על ידי Apigee Edge או על ידי מערכת חיצונית ואז יובא ל-Apigee Edge, חייב להיות משויך לאפליקציית לקוח – שמצוינת על ידי client_id. לכן, גם במקרה שבו מדיניות OAuthV2/GenerateAccessToken ב-Apigee Edge לא תאמת את ההתאמה בין client_id לבין client_secret, המדיניות תאמת ש-client_id תקף, קיים ולא בוטל. לכן, כשלב מקדים בהגדרה, יכול להיות שתצטרכו לייבא מזהי לקוח באמצעות Edge Administrative API.

תהליך המדיניות בנושא OAuth של צד שלישי ב-Apigee

כדי להשתמש באסימונים ממערכות OAuth של צד שלישי ב-Apigee Edge, התהליך ליצירת אסימוני גישה צריך לפעול לפי אחד מהדפוסים הבאים.

אימות חיצוני של פרטי כניסה של לקוח

  1. ServiceCallout כדי לאמת את פרטי הכניסה של הלקוח הנכנס ולקבל אסימון חיצוני.
  2. ExtractVariables או שלב JavaScript כדי לחלץ את האסימון שנוצר חיצונית מהתגובה.
  3. AssignMessage to set the special well-known-variable called oauth_external_authorization_status. הערך חייב להיות true כדי לציין שפרטי הכניסה של הלקוח תקפים.
  4. OAuthV2/GenerateAccessToken עם הרכיב <ExternalAuthorization> שהערך שלו הוא true, ולפחות אחד מהרכיבים <ExternalAccessToken>, <ExternalRefreshToken> או <ExternalAuthorizationCode>.

אימות פנימי של פרטי כניסה של לקוח

  • ServiceCallout כדי לקבל אסימון חיצוני.
  • ExtractVariables או שלב JavaScript כדי לחלץ את האסימון שנוצר חיצונית מהתגובה.
  • OAuthV2/GenerateAccessToken עם הרכיב <ExternalAuthorization> שהערך שלו הוא false, ולפחות אחד מהרכיבים <ExternalAccessToken>, <ExternalRefreshToken> או <ExternalAuthorizationCode>.

הערות לגבי התהליך והגדרת המדיניות

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

  • אחרי ServiceCallout, proxy ל-API צריך לנתח את התגובה כדי לחלץ את סטטוס התוקף, את טוקן הגישה שנוצר חיצונית ואולי גם את טוקן הרענון.

  • במדיניות OAuthV2/GenerateAccessToken, מגדירים את הרכיב <StoreToken> לערך true, ואת הרכיב <ExternalAuthorization> לערך true או false, בהתאם לצורך.

    כשמדיניות OAuthV2/GenerateAccessToken מופעלת, היא קוראת את המשתנה oauth_external_authorization_status. אם המשתנה מוגדר והערך הוא true, ‏ Apigee Edge לא ינסה לאמת את פרטי הכניסה של הלקוח. אם המשתנה לא מוגדר או שהערך שלו לא true, ‏ Apigee Edge ינסה לאמת את פרטי הכניסה של הלקוח.

  • יש שלושה רכיבים במדיניות OAuthV2 שמאפשרים לציין את הנתונים החיצוניים שרוצים לייבא: <ExternalAccessToken>,‏ <ExternalRefreshToken> ו-<ExternalAuthorizationCode>. כל אחד מהאלמנטים האלה מקבל משתנה זרימה. מדיניות Edge תקרא את המשתנה הזה כדי למצוא את אסימון הגישה, אסימון הרענון או קוד ההרשאה שנוצרו חיצונית. אתם צריכים להטמיע מדיניות ולוגיקה כדי להציב את הטוקנים או הקודים החיצוניים במשתנים המתאימים.

    לדוגמה, ההגדרה הבאה במדיניות OAuthV2 אומרת ל-Edge לחפש את האסימון במשתנה הקשר שנקרא external_token.

    <ExternalAccessToken>external_token</ExternalAccessToken>

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

  • לגבי הגדרת המשתנה oauth_external_authorization_status, טכניקה נפוצה להגדרת המשתנה הזה היא שימוש במדיניות AssignMessage עם הרכיב AssignVariable, באופן הבא:

    <AssignMessage name="AssignMessage-SetVariable">
        <DisplayName>Assign Message - Set Variable</DisplayName>
        <AssignVariable>
            <Name>oauth_external_authorization_status</Name>
            <Value>true</Value>
        </AssignVariable>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    </AssignMessage>

    חשוב לזכור שהמדיניות הזו צריכה להיות לפני מדיניות OAuthV2 עם Operation = GenerateAccessToken.

דוגמה למדיניות OAuthV2

מדיניות OAuthV2 הבאה יוצרת אסימון גישה של Apigee Edge, בהנחה ש-Edge מוצא ערך של אסימון במשתנה זרימה external_access_token.

<OAuthV2 name="OAuth-v20-Store-External-Token">
    <ExternalAccessToken>external_access_token</ExternalAccessToken>
    <ExternalAuthorization>true</ExternalAuthorization>
    <Operation>GenerateAccessToken</Operation>
    <GenerateResponse enabled="true">
        <Format>FORM_PARAM</Format>
    </GenerateResponse>
    <ReuseRefreshToken>false</ReuseRefreshToken>
    <StoreToken>true</StoreToken>
    <SupportedGrantTypes>
        <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <ExpiresIn ref='flow.variable'>2400000</ExpiresIn>
</OAuthV2>

באופן תיאורטי, אפשר להשתמש בדפוס הזה עם כל שירות הרשאה של צד שלישי OAuth2.