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