مروری بر سیاست های JWS و JWT

شما در حال مشاهده مستندات Apigee Edge هستید.
به مستندات Apigee X مراجعه کنید .
اطلاعات

این مبحث اطلاعات کلی در مورد JWT (توکن وب JSON) و JWS (امضای وب JSON) و سیاست‌های JWS/JWT آپیجی ارائه می‌دهد که ممکن است برای توسعه‌دهندگان پروکسی آپیجی جالب باشد.

مقدمه

هر دو JWS و JWT معمولاً برای به اشتراک گذاشتن ادعاها یا اظهارات بین برنامه‌های متصل استفاده می‌شوند. سیاست‌های JWS/JWT به پروکسی‌های Edge API این امکان را می‌دهد که:

  • یک JWT یا JWS امضا شده تولید کنید .
  • یک JWT یا JWS امضا شده را تأیید کنید و ادعاهای درون JWS/JWT را مطرح کنید.
  • رمزگشایی یک JWT یا JWS امضا شده بدون اعتبارسنجی امضا.

در دو مورد اخیر، این سیاست همچنین متغیرهایی را تعیین می‌کند که به سیاست‌های اضافی یا خود سرویس‌های backend اجازه می‌دهد ادعاهای اعتبارسنجی شده را بررسی کرده و بر اساس آن ادعاها تصمیم‌گیری کنند.

هنگام استفاده از سیاست تأیید JWS/JWT، یک JWS/JWT نامعتبر رد می‌شود و منجر به وضعیت خطا می‌شود. به طور مشابه، هنگام استفاده از سیاست رمزگشایی JWS/JWT، یک JWS/JWT ناقص منجر به وضعیت خطا خواهد شد.

ویدیوها

برای آشنایی سریع با JWT، یک ویدیوی کوتاه تماشا کنید. اگرچه این ویدیو مختص تولید JWT است، اما بسیاری از مفاهیم برای JWS یکسان هستند.

چه ویدیوی کوتاهی برای آشنایی بیشتر با ساختار JWT.

موارد استفاده

شما می‌توانید از سیاست‌های JWS/JWT برای موارد زیر استفاده کنید:

  • یک JWS/JWT جدید را روی پروکسی یا سمت هدفِ یک پروکسی Edge ایجاد کنید. برای مثال، می‌توانید یک جریان درخواست پروکسی ایجاد کنید که یک JWS/JWT تولید کند و آن را به کلاینت برگرداند. یا می‌توانید یک پروکسی طراحی کنید تا یک JWS/JWT روی جریان درخواست هدف تولید کند و آن را به درخواست ارسالی به هدف متصل کند. سپس این ادعاها برای فعال کردن سرویس‌های backend جهت اعمال پردازش‌های امنیتی بیشتر در دسترس خواهند بود.
  • ادعاهایی را از JWS/JWT که از درخواست‌های ورودی کلاینت، از پاسخ‌های سرویس هدف، از پاسخ‌های سیاست فراخوانی سرویس یا از منابع دیگر به دست آمده است، تأیید و استخراج کنید. Edge امضای JWS/JWT را تأیید می‌کند، چه JWS/JWT توسط شخص ثالث تولید شده باشد و چه توسط خود Edge، با استفاده از الگوریتم‌های RSA یا HMAC.
  • رمزگشایی یک JWS/JWT. رمزگشایی زمانی بیشترین فایده را دارد که همراه با سیاست تأیید JWS/JWT استفاده شود، زمانی که مقدار یک ادعا (JWT) یا سرآیند (JWS/JWT) از درون JWS/JWT باید قبل از تأیید JWS/JWT مشخص باشد.

بخش‌هایی از یک JWS/JWT

یک JWS/JWT امضا شده، اطلاعات را در سه بخش که با نقطه از هم جدا شده‌اند، کدگذاری می‌کند: هدر، پی‌لود و امضا:

header.payload.signature
  • سیاست Generate JWS/JWT هر سه بخش را ایجاد می‌کند.
  • سیاست تأیید JWS/JWT هر سه بخش را بررسی می‌کند.
  • سیاست رمزگشایی JWS/JWT فقط هدر و محتوای داده (payload) را بررسی می‌کند.

یک JWS همچنین از یک قالب جداگانه پشتیبانی می‌کند که محتوای مخرب (payload) را از JWS حذف می‌کند:

header..signature

با یک JWS جدا، محتوای مخرب (payload) جدا از JWS ارسال می‌شود. شما از عنصر <DetachedContent> در سیاست Verify JWS برای مشخص کردن محتوای مخرب خام و رمزگذاری نشده JWS استفاده می‌کنید. سپس سیاست Verify JWS با استفاده از سرآیند و امضا در JWS و محتوای مخرب مشخص شده توسط عنصر <DetachedContent> JWS را تأیید می‌کند.

برای کسب اطلاعات بیشتر در مورد توکن‌ها و نحوه رمزگذاری و امضا آنها، به موارد زیر مراجعه کنید:

تفاوت‌های بین JWS و JWT

شما می‌توانید از JWT یا JWS برای اشتراک‌گذاری ادعاها یا assertionها بین برنامه‌های متصل استفاده کنید. تفاوت اصلی بین این دو، نحوه نمایش payload است:

  • جی دبلیو تی
    • بار داده همیشه یک شیء JSON است
    • بار داده همیشه به JWT متصل است
    • هدر typ توکن همیشه روی JWT تنظیم می‌شود.
  • جی دبلیو اس
    • بار داده می‌تواند با هر قالبی، مانند یک شیء JSON، جریان بایت، جریان هشت‌تایی و موارد دیگر، نمایش داده شود.
    • لازم نیست که payload به JWS متصل باشد.

از آنجا که فرمت JWT همیشه از یک شیء JSON برای نمایش بار داده استفاده می‌کند، سیاست‌های Edge Generate JWT و Verify JWT به صورت داخلی از مدیریت نام‌های ادعای ثبت‌شده‌ی رایج، مانند aud ، iss ، sub و موارد دیگر، پشتیبانی می‌کنند. این بدان معناست که می‌توانید از عناصر سیاست Generate JWT برای تنظیم این ادعاها در بار داده و از عناصر سیاست Verify JWT برای تأیید مقادیر آنها استفاده کنید. برای اطلاعات بیشتر به بخش نام‌های ادعای ثبت‌شده در مشخصات JWT مراجعه کنید.

در کنار پشتیبانی از نام‌های ادعای ثبت‌شده‌ی خاص، سیاست Generate JWT مستقیماً از افزودن ادعاها با نام‌های دلخواه به JWT پشتیبانی می‌کند. هر ادعا یک جفت نام/مقدار ساده است که در آن مقدار می‌تواند از نوع عدد، بولی، رشته، نقشه یا آرایه باشد.

از آنجا که یک JWS می‌تواند از هر نمایش داده‌ای برای بار داده استفاده کند، شما نمی‌توانید ادعاها (Claims) را به بار داده اضافه کنید. سیاست Generate JWS از اضافه کردن ادعاها با نام‌های دلخواه به هدر JWS پشتیبانی می‌کند. همچنین، سیاست‌های JWS از بار داده جدا شده (detached payload) پشتیبانی می‌کنند، که در آن JWS بار داده را حذف می‌کند. بار داده جدا شده به شما امکان می‌دهد JWS و بار داده را جداگانه ارسال کنید و توسط چندین استاندارد امنیتی مورد نیاز است.

جلوگیری از تزریق الگو هنگام استفاده از JWS و JWT

برای جلوگیری از افشای غیرمجاز داده‌ها، هنگام استفاده از سیاست‌های GenerateJWT یا GenerateJWS، این دستورالعمل‌ها را دنبال کنید:

  • از ارجاع مستقیم به ورودی کاربر خودداری کنید: هرگز از ورودی‌های غیرقابل اعتماد (مانند request.queryparam.* یا request.header.* ) مستقیماً در یک ویژگی ref که از قالب‌بندی پشتیبانی می‌کند، استفاده نکنید.
  • پاکسازی ورودی: اگر مجبور به استفاده از داده‌های خارجی در یک ادعای JWT/JWS هستید، ابتدا از یک سیاست AssignMessage برای حذف هرگونه آکولاد ( { } ) یا سایر کاراکترهای الگو از ورودی قبل از ارجاع به آن استفاده کنید.
  • از ادعاهای صریح برای رشته‌ها استفاده کنید: برای ادعاهای ساده رشته، type="map" اجتناب کنید. استفاده از type="string" پیش‌فرض از قالب‌بندی ضمنی مقدار ارجاع‌شده جلوگیری می‌کند.
  • به تناقض رفتاری بین سیاست‌های تأیید و تولید توجه کنید: سیاست‌های تولید JWS و JWT در مورد قالب‌بندی، رفتاری متفاوت از سیاست‌های تأیید دارند.

درباره الگوریتم‌های امضا

سیاست‌های تأیید JWS/JWT و تولید JWS/JWT از الگوریتم‌های RSA، RSASSA-PSS، ECDSA و HMAC پشتیبانی می‌کنند و از مجموع‌های کنترلی SHA2 با قدرت بیت ۲۵۶، ۳۸۴ یا ۵۱۲ استفاده می‌کنند. سیاست رمزگشایی JWS/JWT صرف نظر از الگوریتمی که برای امضای JWS/JWT استفاده شده است، کار می‌کند.

الگوریتم HMAC

الگوریتم HMAC برای ایجاد امضا (که به عنوان امضای JWS/JWT نیز شناخته می‌شود) و تأیید امضا، به یک راز مشترک، معروف به کلید مخفی، متکی است.

حداقل طول کلید مخفی به قدرت بیت الگوریتم بستگی دارد:

  • HS256: حداقل طول کلید ۳۲ بایت
  • HS386: حداقل طول کلید ۴۸ بایت
  • HS512: حداقل طول کلید ۶۴ بایت

الگوریتم RSA

الگوریتم RSA از یک جفت کلید عمومی/خصوصی برای امضای رمزنگاری استفاده می‌کند. در امضاهای RSA، طرف امضاکننده از یک کلید خصوصی RSA برای امضای JWS/JWT استفاده می‌کند و طرف تأییدکننده از کلید عمومی RSA منطبق برای تأیید امضا روی JWS/JWT استفاده می‌کند. هیچ الزام اندازه‌ای برای کلیدها وجود ندارد.

الگوریتم RSASSA-PSS

الگوریتم RSASSA-PSS به‌روزرسانی الگوریتم RSA است. مانند RSS، RSASSA-PSS از یک جفت کلید عمومی/خصوصی RSA برای امضای رمزنگاری استفاده می‌کند. قالب کلید همانند RSS است. طرف امضاکننده از یک کلید خصوصی برای امضای JWS/JWT استفاده می‌کند و طرف تأییدکننده از کلید عمومی منطبق برای تأیید امضا روی JWS/JWT استفاده می‌کند. هیچ الزام اندازه‌ای برای کلیدها وجود ندارد.

الگوریتم ECDSA

الگوریتم امضای دیجیتال منحنی بیضوی (ECDSA) یک الگوریتم رمزنگاری منحنی بیضوی با منحنی‌های P-256، P-384 و P-521 است. وقتی از الگوریتم‌های ECDSA استفاده می‌کنید، الگوریتم نوع کلید عمومی و خصوصی مورد نیاز شما را تعیین می‌کند:

الگوریتم منحنی نیاز کلیدی
ES256 پ-۲۵۶ کلیدی که از منحنی P-256 تولید شده است (همچنین با نام‌های secp256r1 یا prime256v1 نیز شناخته می‌شود)
ES384 پ-۳۸۴ کلیدی که از منحنی P-384 تولید شده است (همچنین با نام secp384r1 شناخته می‌شود)
ES512 پی-۵۲۱ کلیدی که از منحنی P-521 تولید شده است (همچنین با نام secp521r1 شناخته می‌شود)

الگوریتم‌های رمزگذاری کلید

سیاست‌های JWS/JWT از تمام الگوریتم‌های رمزگذاری کلیدی پشتیبانی‌شده توسط OpenSSL پشتیبانی می‌کنند.

استفاده از مجموعه کلید وب JSON (JWKS) برای تأیید JWS/JWT

وقتی یک JWS/JWT امضا شده را تأیید می‌کنید، باید کلید عمومی مرتبط با کلید خصوصی مورد استفاده برای امضای توکن را ارائه دهید. شما دو گزینه برای ارائه کلید عمومی به سیاست‌های تأیید JWS/JWT دارید:

  • از مقدار واقعی کلید عمومی (که معمولاً در یک متغیر جریان ارائه می‌شود) استفاده کنید، یا
  • از یک کلید عمومی که در JWKS پیچیده شده است استفاده کنید.

درباره JWKS

JWKS یک ساختار JSON است که مجموعه‌ای از کلیدهای وب JSON (JWK) را نشان می‌دهد. JWK یک ساختار داده JSON است که یک کلید رمزنگاری را نشان می‌دهد. JWK و JWKS در RFC7517 شرح داده شده‌اند. به مثال‌های JKWS در پیوست A مراجعه کنید. مثال مجموعه کلیدهای وب JSON

ساختار JWKS

RFC7517 عناصر کلیدی JWKS را برای هر نوع کلید، مانند "RSA" یا "EC" شرح می‌دهد. به عنوان مثال، بسته به نوع کلید، این پارامترها می‌توانند شامل موارد زیر باشند:

  • kty - نوع کلید، مانند "RSA" یا "EC".
  • بچه (شناسه کلید) - می‌تواند هر مقدار دلخواهی باشد (در یک مجموعه کلید، موارد تکراری وجود ندارد). اگر JWT ورودی دارای شناسه کلیدی باشد که در مجموعه JWKS وجود دارد، آنگاه سیاست از کلید عمومی صحیح برای تأیید امضای JWS/JWT استفاده خواهد کرد.

در زیر نمونه‌هایی از عناصر اختیاری و مقادیر آنها آمده است:

  • alg - الگوریتم کلید. باید با الگوریتم امضا در JWS/JWT مطابقت داشته باشد.
  • استفاده - در صورت وجود، باید امضا شود.

JWKS زیر شامل عناصر و مقادیر مورد نیاز است و در Edge معتبر خواهد بود (از https://www.googleapis.com/oauth2/v3/certs ):

{
   "keys":[
      {
         "kty":"RSA",
         "alg":"RS256",
         "use":"sig",
         "kid":"ca04df587b5a7cead80abee9ea8dcf7586a78e01",
         "n":"iXn-WmrwLLBa-QDiToBozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt7-V7KDjCq0_Nkd-X9rMRV5LKgCa0_F8YgI30QS3bUm9orFryrdOc65PUIVFVxIwMZuGDY1hj6HEJVWIr0CZdcgNIll06BasclckkUK4O-Eh7MaQrqb646ghFlG3zlgk9b2duHbDOq3s39ICPinRQWC6NqTYfqg7E8GN_NLY9srUCc_MswuUfMJ2cKT6edrhLuIwIj_74YGkpOwilr2VswKsvJ7dcoiJxheKYvKDKtZFkbKrWETTJSGX2Xeh0DFB0lqbKLVvqkM2lFU2Qx1OgtTnrw",
         "e":"AQAB"
      },
      {
          "kty":"EC",
          "alg":"ES256",
          "use":"enc",
          "kid":"k05TUSt7-V7KDjCq0_N"
          "crv":"P-256",
          "x":"Xej56MungXuFZwmk_xccvsMpCtXmqhvEEMCmHyAmKF0",
          "y":"Bozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt",
      }
   ]
}

طراحی پروکسی شما برای استفاده از JWKS

وقتی یک JWS/JWT از یک صادرکننده دریافت می‌شود، اغلب صادرکننده یک شناسه کلید (یا کد) را در هدر JWS/JWT وارد می‌کند. این کلید به گیرنده JWS/JWT می‌گوید که چگونه کلید عمومی یا مخفی لازم برای تأیید امضا روی JWS/JWT امضا شده را پیدا کند.

به عنوان مثال، فرض کنید یک صادرکننده، JWT را با یک کلید خصوصی امضا می‌کند. «شناسه کلید» کلید عمومی منطبق را برای استفاده جهت تأیید JWT مشخص می‌کند. فهرست کلیدهای عمومی معمولاً در برخی از نقاط پایانی شناخته شده، به عنوان مثال: https://www.googleapis.com/oauth2/v3/certs ، موجود است.

این توالی اساسی است که Edge (یا هر پلتفرمی که با JWKS کار می‌کند) باید برای کار با JWS/JWT که دارای JWKS است، انجام دهد:

  1. هدر JWS/JWT را بررسی کنید تا شناسه کلید (kid) را پیدا کنید.
  2. هدر JWS/JWT را بررسی کنید تا الگوریتم امضا (alg) مانند RS256 را پیدا کنید.
  3. فهرست کلیدها و شناسه‌ها را از JWKS مربوط به نقطه پایانی شناخته‌شده برای یک صادرکننده‌ی مشخص بازیابی کنید.
  4. کلید عمومی را از لیست کلیدها با شناسه کلید ذکر شده در سرآیند JWS/JWT و با الگوریتم تطبیق، در صورتی که کلید JWKS الگوریتم را مشخص کند، استخراج کنید.
  5. از آن کلید عمومی برای تأیید امضا در JWS/JWT استفاده کنید.

به عنوان یک توسعه‌دهنده پروکسی Edge API، برای انجام تأیید JWS/JWT باید موارد زیر را انجام دهید:

  1. فهرست کلیدها و شناسه‌ها را از نقطه پایانی شناخته‌شده برای یک صادرکننده مشخص بازیابی کنید. می‌توانید برای این مرحله از یک سیاست فراخوانی سرویس استفاده کنید.
  2. در سیاست Verify JWS/JWT، محل JWS/JWT را در عنصر <Source> و JWKS payload را در عنصر <PublicKey/JWKS> مشخص کنید. برای مثال، برای سیاست VerifyJWT:
    <VerifyJWT name="JWT-Verify-RS256">
        <Algorithm>RS256</Algorithm>
        <Source>json.jwt</Source>
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
        <PublicKey>
            <JWKS ref="public.jwks"/>
        </PublicKey>
        <Subject>apigee-seattle-hatrack-montage</Subject>
        <Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
        <Audience>urn://c60511c0-12a2-473c-80fd-42528eb65a6a</Audience>
        <AdditionalClaims>
            <Claim name="show">And now for something completely different.</Claim>
        </AdditionalClaims>
    </VerifyJWT>

سیاست تأیید JWT همه کارهای دیگر را انجام می‌دهد:

  • اگر کلیدی با شناسه کلید (Key ID) که با شناسه کلید (kid) ادعا شده در JWT مطابقت دارد، در JWKS یافت نشود، آنگاه سیاست تأیید JWT خطایی صادر می‌کند و JWT را اعتبارسنجی نمی‌کند.
  • اگر JWT ورودی دارای شناسه کلید (kid) در هدر نباشد، این نگاشت keyid به verification-key امکان‌پذیر نیست.

به عنوان طراح پروکسی، شما مسئول تعیین کلید مورد استفاده هستید؛ در برخی موارد، این کلید ممکن است یک کلید ثابت و کدگذاری شده باشد.