שימוש בטוקנים של OAuth מסוג JWT

הדף הזה רלוונטי ל-Apigee ול-Apigee Hybrid.

לעיון במסמכי התיעוד של Apigee Edge

בנושא הזה מוסבר איך ליצור, לאמת ולרענן אסימוני גישה מסוג JWT באמצעות מדיניות OAuthV2.

מבוא

פעולות ה-JWT מאפשרות למדיניות OAuthV2 ליצור, לאמת ולרענן אסימוני גישה שתואמים ל-IETF RFC 9068, תקן שמתאר איך להנפיק אסימוני גישה בפורמט JWT. בדרך כלל משתמשים ב-JWT כדי לשתף טענות או הצהרות בין אפליקציות מקושרות. אפשר להשתמש בפורמט JWT כדי להנפיק אסימוני גישה של OAuthV2 במקום להנפיק אסימוני גישה אטומים.

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

איור 1: פורמט סריאלי של JWT שכולל כותרת, מטען ייעודי (payload) וחתימה, שמופרדים באמצעות נקודות.

התוכן המוצפן של הרכיבים האלה תלוי באופן שבו מגדירים את מדיניות OAuthV2. במדיניות, מציינים פרמטרים כמו אלגוריתם החתימה ורכיבי מטען ייעודי כמו נושא ושם. לדוגמה, יכול להיות שהכותרת תפוענח כ-{"alg":"HS256","typ":"at+JWT"}, והמטען יפוענח כ-{"sub":"ABC1234567","iat":1516239022}.

הכותרת מציינת הצהרת typ (תמיד "at+JWT) והצהרת alg, שמציינת את האלגוריתם ששימש לחתימה על ה-JWT. ‫Apigee תומך באלגוריתמים RSA ו-HMAC: ‏ RS(256,384,512) ו-HS(256,384,512).

Payload

המטען הייעודי (payload) מורכב מהצהרות לגבי הישות. חלק מהטענות צריך לספק בהגדרת המדיניות, ואחרות נוצרות באופן אוטומטי על ידי זמן הריצה של Apigee. המדיניות תומכת בתלונות הבאות:

תביעה תיאור סופק על ידי
iss הנפקן של האסימון. הערך הזה מוגדר באופן הבא: (http|https)://{domain-name-for-proxy}/{proxy-basePath}. לדוגמה: https://api.mycompany.com/auth/v2. Apigee
sub מזהה הלקוח או מזהה הבעלים של המשאב (במקרה של סוגי סיסמה או מענק הרשאה). אם הפרמטר appEndUserId מופיע בבקשה, הערך הזה משמש כמזהה הבעלים של המשאב. אפשר לקבוע איפה הערך הזה מוגדר באמצעות הרכיב <AppEndUser> במדיניות OAuthV2. מפתח API
jti מזהה ייחודי, שמיוצג כמחרוזת אקראית שמגובה על ידי UUID, כדי לזהות באופן ייחודי את האסימון. Apigee
exp מועד התפוגה, כלומר הזמן שאחריו הטוקן נחשב לא תקף. הערך מבוטא בזמן אפוקה (בשניות). Apigee
iat הזמן שבו הונפק האסימון, כלומר הזמן שבו הוא נוצר. הערך מופיע בפורמט epoch time (בשניות). Apigee
client_id המזהה הייחודי של אפליקציית הלקוח. מפתח API
scope היקף ההרשאות של OAuth שהוקצה לטוקן. מידע נוסף זמין במאמר בנושא עבודה עם היקפי הרשאות של OAuth. מפתח API

חתימה

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

למידע נוסף על אסימוני גישה מסוג OAuth 2.0 בפורמט JWT, תוכלו לעיין ב-IETF RFC 9068: JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens.

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

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

בתהליך יצירה

משתמשים בפעולות GenerateJWTAccessToken ו-GenerateJWTAccessTokenImplicitGrant כדי ליצור אסימון גישה מסוג JWT באמצעות מדיניות OAuthV2. הפעולות האלה דומות לפעולות המסורתיות GenerateAccessToken ו-GenerateAccessTokenImplicitGrant של המדיניות. ההבדל העיקרי הוא שפעולת ה-JWT מחזירה אסימון גישה בפורמט JWT במקום אסימון מחרוזת אטומה. אפשר גם לעיין במאמר בנושא קבלת טוקנים מסוג OAuth 2.0.

בדוגמאות הבאות אפשר לראות איך משתמשים בפעולות האלה במדיניות OAuthV2. בדוגמאות נעשה שימוש בסוג ההרשאה client_credentials, אבל אפשר להשתמש בכל אחד מסוגי ההרשאות הנתמכים בפעולות האלה.

יצירת אסימון בפורמט JWT שחתום באמצעות אלגוריתם HMAC

מציינים את הרכיב <Algorithm> עם אחד מאלגוריתמי ה-HMAC‏ (HS256/HS384/HS512). צריך לספק גם את <SecretKey>. בדוגמה הבאה מוצגת מדיניות שמוגדרת ליצירת JWT שחתום באמצעות אלגוריתם HS512 באמצעות מפתח סודי שצוין.

<OAuthV2 name="generate-policy">
  <Operation>GenerateJWTAccessToken</Operation>
  <SupportedGrantTypes>
    <GrantType>client_credentials</GrantType>
  </SupportedGrantTypes>
  <GenerateResponse enabled="true"/>
  <Algorithm>HS512</Algorithm>
  <SecretKey>
    <Value ref="private.mysecretkey"/>
  </SecretKey>
  <ExpiresIn ref="kvm.oauth.expires_in">3600000</ExpiresIn>
</OAuthV2>

יצירת אסימון בפורמט JWT שנחתם באמצעות אלגוריתם RSA

מציינים אחד מאלגוריתמי ה-RSA (אחד מהאלגוריתמים RS256/RS384/RS512) ברכיב <Algorithm>, ומספקים את המפתח הפרטי ברכיב <PrivateKey>. בדוגמה הבאה מוצגת מדיניות שהוגדרה ליצירת JWT בחתימה עם מפתח פרטי RSA באמצעות האלגוריתם RS256.

<OAuthV2 name="generate-policy">
  <Operation>GenerateJWTAccessToken</Operation>
  <SupportedGrantTypes>
    <GrantType>client_credentials</GrantType>
  </SupportedGrantTypes>
  <GenerateResponse enabled="true"/>
  <Algorithm>RS256</Algorithm>
  <PrivateKey>
    <Value ref="private.rsa-privatekey-1"/>
  </PrivateKey>
  <ExpiresIn ref="kvm.oauth.expires_in">3600000</ExpiresIn>
</OAuthV2>

יצירת אסימון בפורמט JWT עם סוג ההרשאה המרומז

הפעולה GenerateJWTAccessTokenImplicitGrant יוצרת אסימון גישה מסוג JWT באמצעות סוג ההרשאה המרומז. הוא מקצה לטוקן באופן אוטומטי את סוג ההרשאה המרומז, ולכן אין צורך ברכיב <SupportedGrantTypes>. מכיוון שזהו JWT, נדרש הרכיב <Algorithm>. בדוגמה הבאה מוצג שימוש באלגוריתם RS256. לכן, חובה להשתמש ברכיב <PrivateKey>. מידע נוסף זמין במאמר בנושא שימוש בסוג ההרשאה המרומז.

<OAuthV2 name="generate-policy">
  <Operation>GenerateJWTAccessTokenImplicitGrant</Operation>
  <GenerateResponse enabled="true"/>
  <Algorithm>RS256</Algorithm>
  <PrivateKey>
    <Value ref="private.rsa-privatekey-1"/>
  </PrivateKey>
  <ExpiresIn ref="kvm.oauth.expires_in">3600000</ExpiresIn>
</OAuthV2>

מוודא

משתמשים בVerifyJWTAccessToken פעולה כדי לאמת אסימון גישה מסוג JWT באמצעות מדיניות OAuthV2. הפעולה הזו דומה לפעולה VerifyAccessToken . ההבדל הוא שהפעולה VerifyJWTAccessToken חלה על אסימונים בפורמט JWT, בעוד שהפעולה VerifyAccessToken חלה על אסימונים אטומים.

אימות של אסימון גישה מסוג JWT שנחתם באמצעות אלגוריתם HMAC

בדוגמה הבאה מוצג אופן ההגדרה של מדיניות OAuthV2 כדי לאמת אסימון JWT שנחתם באמצעות אלגוריתם HS512. כשמשתמשים בפעולה VerifyJWTAccessToken עם אלגוריתם HMAC, צריך להשתמש ברכיב <SecretKey> בהגדרת המדיניות כדי לציין את המפתח הסודי ששימש לחתימה על ה-JWT.

<OAuthV2 name="OAuthV2-verify-jwt">
  <Operation>VerifyJWTAccessToken</Operation>
  <Algorithm>HS512</Algorithm>
  <SecretKey>
    <Value ref="private.mysecretkey"/>
  </SecretKey>
</OAuthV2>

אימות של אסימון גישה מסוג JWT שנחתם באמצעות אלגוריתם RSA

בדוגמה הבאה מוצג אופן ההגדרה של מדיניות OAuthV2 כדי לאמת אסימון JWT שנחתם באמצעות אלגוריתם RS512. כשמשתמשים בפעולה VerifyJWTAccessToken עם אלגוריתם RSA, בהגדרת המדיניות צריך להשתמש ברכיב <PublicKey> כדי לציין את המפתח הציבורי שתואם למפתח הפרטי ששימש לחתימה על ה-JWT.

<OAuthV2 name="OAuthV2-verify-jwt">
  <Operation>VerifyJWTAccessToken</Operation>
  <Algorithm>RS512</Algorithm>
  <PublicKey>
    <Value ref="propertyset.non-secrets.rsa-publickey-1"/>
  </PublicKey>
</OAuthV2>

רענון

משתמשים בRefreshJWTAccessToken פעולה כדי לרענן אסימון גישה מסוג JWT. הפעולה הזו דומה לפעולה המסורתית של המדיניות RefreshAccessToken. אפשר לעיין גם במאמר רענון של אסימון גישה.

רענון של טוקן גישה עם חתימת HMAC

דוגמת המדיניות הבאה ממחישה איך להגדיר את מדיניות OAuthV2 כדי לרענן אסימון JWT שנחתם באמצעות אלגוריתם HMAC. במקרה הזה, חובה להשתמש ברכיבים <SecretKey> ו-<Algorithm>.

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

<OAuthV2 name="RefreshAccessToken">
    <Operation>RefreshJWTAccessToken</Operation>
    <GenerateResponse enabled="true"/>
    <Algorithm>HS512</Algorithm>
    <SecretKey>
      <Value ref="private.mysecretkey"/>
    </SecretKey>
    <RefreshTokenExpiresIn ref="kvm.oauth.expires_in">3600000</RefreshTokenExpiresIn>
</OAuthV2>

רענון של אסימון גישה מסוג JWT בחתימת RSA

בדוגמה הבאה של מדיניות אפשר לראות איך מגדירים את מדיניות OAuthV2 כדי לרענן אסימון JWT שנחתם באמצעות אלגוריתם RSA. אפשר לעיין גם במאמר רענון של אסימון גישה.

<OAuthV2 name="RefreshAccessToken">
    <Operation>RefreshJWTAccessToken</Operation>
    <GenerateResponse enabled="true"/>
    <Algorithm>RS256</Algorithm>
    <PrivateKey>
      <Value ref="private.rsa-privatekey-1"/>
    </PrivateKey>
    <RefreshTokenExpiresIn ref="kvm.oauth.expires_in">3600000</RefreshTokenExpiresIn>
</OAuthV2>

דוגמה לתגובת טוקן

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

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6ImF0K0pXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
  "token_type": "Bearer",
  "developer.email": "developer@example.org",
  "token_type": "Bearer",
  "issued_at": "1658352381404",
  "expires_in": 1799,
  "refresh_token": "rVSmm3QaNa0xBVFbUISz1NZI15akvgLJ",
  "refresh_token_issued_at": "1658352381404",
  "refresh_token_expires_in": 86399,
  "refresh_token_status": "Approved",
  "refresh_count": "0",
  "organization_name": "cerruti",
  "api_product_list_json": [ "TestingProduct" ]
}

סיכום של רכיבי המדיניות הנדרשים

בטבלה הבאה מתוארים רכיבים ספציפיים ל-JWT שמופיעים בדוגמאות שלמעלה:

רכיב סוג הערות
אלגוריתם ערך סטטי מציין את האלגוריתם שמשמש לחתימת הטוקן.
SecretKey ערך שהופנה אליו מכיל את המפתח הסודי שמשמש לאימות או לחתימה על אסימונים באמצעות אלגוריתם HMAC: ‏ HS ‏ (256/384/512).
PrivateKey ערך שהופנה אליו מציין את המפתח הפרטי שמשמש ליצירת האסימון. צריך להשתמש רק אם האלגוריתם הוא אלגוריתם RSA: ‏ RS (256/384/512).
PublicKey ערך שהופנה אליו המפתח הציבורי שמשמש לאימות הטוקן. השימוש מותר רק אם האלגוריתם הוא אלגוריתם RSA: ‏ RS ‏ (256/384/512).

רכיבי מדיניות שלא נתמכים

רכיבי המדיניות הבאים של OAuthV2 לא נתמכים בתצורות של אסימוני JWT:

רכיב הערות
ExternalAuthorization כשיוצרים אסימון גישה מסוג JWT, מדיניות OAuthV2 מאמתת את מזהה הלקוח ואת הסוד.
ExternalAccessToken כשיוצרים אסימון גישה מסוג JWT, האסימון נחתם על ידי Apigee והטענות מסופקות על ידי Apigee כברירת מחדל או דרך הגדרת המדיניות. המדיניות תומכת ב-ExternalRefreshToken, שיכול לעזור בתרחישי שימוש של העברה.
RFCCompliantRequestResponse היצירה והרענון של אסימוני גישה מסוג JWT תואמים ל-RFC כברירת מחדל.

הערות שימוש

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