JWS 및 JWT 정책 개요

이 페이지는 ApigeeApigee Hybrid에 적용됩니다.

Apigee Edge 문서 보기

이 주제에서는 JWT(JSON 웹 토큰) 및 JWS(JSON 웹 서명)와 Apigee 프록시 개발자가 관심을 가질 수 있는 Apigee JWS/JWT 정책에 대한 일반적인 정보를 제공합니다.

소개

일반적으로 JWS와 JWT 모두 연결된 애플리케이션 간의 클레임 또는 어설션을 공유하는 데 사용됩니다. JWS/JWT 정책은 Apigee API 프록시를 사용하여 다음을 수행할 수 있습니다.

  • 서명된 JWT, JWS 또는 암호화된 JWT생성합니다.
  • 서명된 JWT, JWS 또는 암호화된 JWT확인하고 JWS/JWT 내에서 선택한 클레임을 확인합니다.
  • 서명을 검증하거나 암호화된 JWT 또는 JWS를 복호화하지 않고 서명 또는 암호화된 JWT 또는 JWS디코딩합니다. JWS의 경우 DecodeJWS 정책은 JWS 헤더에 있는 클레임만 디코딩할 수 있습니다. 암호화된 JWT의 경우 DecodeJWT 정책은 암호화되지 않은 헤더만 디코딩할 수 있습니다.

후자의 두 경우 정책은 흐름 변수도 설정합니다. 이렇게 하면 Apigee 흐름의 후속 정책에서 JWT 또는 JWS의 클레임을 검사하고 이러한 클레임을 기반으로 결정을 내리거나 해당 정보를 백엔드 서비스에 전파할 수 있습니다.

VerifyJWS 또는 VerifyJWT 정책을 사용하면 잘못된 JWS/JWT가 거부되고 오류 조건이 발생합니다. 마찬가지로 DecodeJWS 또는 DecodeJWT 정책을 사용하는 경우 잘못된 JWS/JWT로 오류 조건이 발생합니다.

동영상

JWT에 대한 간단한 소개 동영상을 시청하세요. 이 동영상은 JWT를 생성하는 데만 해당하지만 대부분의 개념은 JWS와 동일합니다.

JWT 구조에 대해 자세히 알아볼 수 있는 짧은 동영상입니다.

사용 사례

JWS/JWT 정책을 사용하여 다음을 수행할 수 있습니다.

  • Apigee 프록시의 프록시 또는 대상 엔드포인트 측에서 새 JWS/JWT를 생성합니다. 예를 들어 JWS/JWT를 생성하고 클라이언트에 반환하는 프록시 요청 흐름을 만들 수 있습니다. 또는 대상 요청 흐름에서 JWS/JWT를 생성하고 프록시로 전송되는 요청에 연결하도록 프록시를 설계할 수 있습니다. 그런 다음 백엔드 서비스가 추가 보안 처리를 적용할 수 있도록 JWS/JWT 및 해당 클레임을 사용할 수 있습니다.
  • 수신 클라이언트 요청, 대상 서비스 응답, 서비스 콜아웃 정책 응답 또는 다른 소스에서 가져온 JWS/JWT에서 클레임을 확인하고 추출합니다. 서명된 JWS/JWT의 경우 Apigee는 서명을 확인하기 위해 RSA, ECDSA 또는 HMAC 알고리즘 중 하나를 사용하여 JWS/JWT가 Apigee 또는 제3자에 의해 생성되었는지 여부를 확인합니다. 암호화된 JWT의 경우 Apigee는 지원되는 JWA 암호화 알고리즘 중 하나를 사용하여 JWT를 복호화합니다(IETF RFC 7518 참조).
  • JWS/JWT를 디코딩합니다. 디코딩은 서명된 JWS/JWT를 확인하거나 암호화된 JWT를 복호화하기 전에 JWS/JWT 내에서 클레임(JWT) 또는 헤더(JWS/JWT)의 값을 알아야 하는 경우 JWS/JWT 확인 정책과 함께 사용할 때 가장 유용합니다.

JWS/JWT를 구성하는 요소

서명된 JWS/JWT는 점으로 구분된 세 부분으로 정보를 인코딩합니다.

Header.Payload.Signature
  • JWS/JWT 생성 정책은 세 부분을 모두 만듭니다.
  • JWS/JWT 확인 정책은 세 부분을 모두 검사합니다.
  • DecodeJWS 정책은 헤더만 검사합니다. DecodeJWT 정책은 헤더 및 페이로드만 검사합니다.

JWS는 JWS에서 페이로드를 생략하는 분리 형식도 지원합니다.

Header..Signature

분리 JWS를 사용하면 페이로드가 JWS와 별도로 전송됩니다. JWS 확인 정책의 <DetachedContent> 요소를 사용하여 인코딩되지 않은 원시 JWS 페이로드를 지정합니다. 그런 다음 JWS 확인 정책은 JWS의 헤더 및 서명과 <DetachedContent> 요소에 지정된 페이로드를 사용하여 JWS를 확인합니다.

암호화된 JWT는 점으로 구분된 다섯 부분으로 정보를 인코딩합니다.

Header.Key.InitializationVector.Payload.AuthenticationTag

GenerateJWT 및 VerifyJWT 정책은 이러한 모든 부분을 만들거나 검사합니다. DecodeJWT는 암호화되지 않은 헤더만 검사할 수 있습니다.

토큰과 인코딩, 서명 또는 암호화 방법에 대해 자세히 알아보려면 관련 표준 문서를 참조하세요.

JWS와 JWT 간 차이점

JWT 또는 JWS를 사용하여 연결된 애플리케이션 간에 클레임 또는 어설션을 공유할 수 있습니다. 이 둘의 주요 차이점은 페이로드를 나타냅니다.

  • JWT
    • 페이로드는 항상 JSON 객체입니다.
    • 페이로드는 항상 JWT에 연결됩니다.
    • 토큰의 typ 헤더는 항상 JWT로 설정됩니다.
    • 페이로드는 서명되거나 암호화될 수 있습니다.
  • JWS
    • 페이로드는 JSON 객체, 바이트 스트림, 옥텟 스트림 등의 모든 형식으로 표현될 수 있습니다.
    • 페이로드는 JWS에 연결할 필요가 없습니다.
    • 헤더와 페이로드는 항상 서명됩니다. JWS는 암호화를 지원하지 않습니다.

JWT 형식은 항상 JSON 객체를 사용하여 페이로드를 나타내기 때문에 Apigee GenerateJWT 및 VerifyJWT 정책에는 기본적으로 aud, iss, sub 등과 같은 일반적인 등록된 클레임 이름을 처리하는 기본 지원 기능이 있습니다. 즉, GenerateJWT 정책의 요소를 사용하여 페이로드에 이러한 클레임을 설정하고 VerifyJWT 정책의 요소를 사용하여 값을 확인할 수 있습니다. 자세한 내용은 JWT 사양의 등록된 클레임 이름 섹션을 참조하세요.

GenerateJWT 정책은 특정한 등록된 클레임 이름을 지원할 뿐만 아니라 JWT의 페이로드 또는 헤더에 임의 이름의 클레임 추가를 직접 지원합니다. 각 클레임은 단순한 이름/값 쌍이며 값은 number, boolean, string, map, array 유형일 수 있습니다.

GenerateJWS를 사용할 때는 페이로드를 나타내는 컨텍스트 변수를 제공합니다. JWS는 페이로드의 모든 데이터 표현을 사용할 수 있으므로 JWS에는 '페이로드 클레임' 이라는 개념이 없으며 GenerateJWS 정책은 페이로드에 임의 이름의 클레임을 추가하는 것을 지원하지 않습니다. GenerateJWS 정책을 사용하여 JWS의 헤더에 임의 이름의 클레임을 추가할 수 있습니다. 또한 JWS 정책은 JWS가 페이로드를 생략하는 분리 페이로드를 지원합니다. 분리 페이로드를 사용하면 JWS와 페이로드를 별도로 전송할 수 있습니다. 분리된 페이로드를 사용하면 특히 대규모 페이로드의 경우 공간 효율을 높일 수 있으며 여러 보안 표준에서 요구합니다.

서명과 암호화 비교

Apigee는 서명되거나 암호화된 JWT를 생성할 수 있습니다. 페이로드가 보안 비밀일 필요는 없지만 리더에게 무결성 및 부인 방지 보장을 제공하는 것이 중요한 경우 서명된 JWT를 선택합니다. 서명된 JWT는 JWT가 서명된 이후 페이로드가 변경되지 않았고 비공개 키 소유자가 JWT를 서명했음을 리더에게 보장합니다. 페이로드가 보안 비밀이어야 하는 경우 암호화된 JWT를 선택합니다. 암호화된 JWT는 적절한 키 소유자만 복호화할 수 있으므로 페이로드에 기밀성을 제공합니다.

특히 암호화된 JWT가 비대칭 암호화 알고리즘(RSA, ECDSA)을 사용하는 경우에는 암호화된 JWT와 서명된 JWT를 함께 사용할 수 있습니다. 이 경우 암호화 키가 공개 상태이기 때문에 해당 JWT의 제작자의 ID를 확인할 수 없습니다. 이 문제를 해결하려면 서명을 암호화와 결합합니다. 일반적인 패턴은 다음과 같습니다.

  • 페이로드에 서명하여 JWS 또는 서명된 JWT를 생성합니다.
  • 서명된 결과를 암호화하여 암호화된 JWT를 생성합니다.

이 방식을 사용하여 암호화된 JWT 내에 서명된 페이로드를 삽입하면 부인 방지 및 기밀성이 모두 보장됩니다. Apigee 정책은 이러한 조합을 생성, 디코딩, 확인할 수 있습니다.

서명 알고리즘

서명된 JWT의 경우 JWS/JWT 확인 및 JWS/JWT 생성 정책은 비트 강도가 256, 384, 512인 SHA2 체크섬을 사용하여 RSA, RSASSA-PSS, ECDSA, HMAC 알고리즘을 지원합니다. DecodeJWS 및 DecodeJWT 정책은 JWS/JWT 서명에 사용된 알고리즘과 관계없이 작동합니다.

HMAC 알고리즘

HMAC 알고리즘은 서명(JWS/JWT 서명이라고도 함)을 만들고 서명을 확인하기 위해 보안 비밀 키라고 하는 공유 비밀번호를 사용합니다.

보안 비밀 키의 최소 길이는 알고리즘의 비트 강도에 따라 다릅니다.

  • HS256: 최소 32바이트 키 길이
  • HS384: 최소 48바이트 키 길이
  • HS512: 최소 64바이트 키 길이

RSA 알고리즘

RSA 알고리즘은 암호화 서명에 공개 키/비공개 키 쌍을 사용합니다. JWA 사양에서는 이러한 옵션을 나타내기 위해 RS256, RS384, RS512라는 명칭을 사용합니다. RSA 서명을 사용하면 서명 당사자는 RSA 비공개 키를 사용하여 JWS/JWT에 서명하고 확인 당사자는 일치하는 RSA 공개 키를 사용하여 JWS/JWT의 서명을 확인합니다. 키에는 크기 요구사항이 없습니다.

RSASSA-PSS 알고리즘

RSASSA-PSS 알고리즘은 RSA 알고리즘을 업데이트한 것으로 PS256, PS384, PS512라는 명칭을 사용합니다. RS* 변형과 마찬가지로 RSASSA-PSS는 암호화 서명에 RSA 공개 키/비공개 키 쌍을 사용합니다. 키의 형식, 메커니즘, 크기 제한은 RS* 알고리즘과 동일합니다.

ECDSA 알고리즘

ECDSA(타원 곡선 디지털 서명 알고리즘) 알고리즘 세트는 P-256, P-384, P-521 곡선이 있는 타원곡선 암호 알고리즘입니다. ECDSA 알고리즘을 사용하는 경우 알고리즘은 지정해야 하는 공개 및 비공개 키의 유형을 결정합니다.

알고리즘 곡선 키 요구사항
ES256 P-256 P-256 곡선에서 생성된 키(secp256r1 또는 prime256v1이라고도 함)
ES384 P-384 P-384 곡선에서 생성된 키(secp384r1이라고도 함)
ES512 P-521 P-521 곡선에서 생성된 키(secp521r1이라고도 함)

암호화 알고리즘

GenerateJWT 및 VerifyJWT를 사용하여 암호화된 JWT를 처리할 때 정책은 다음 알고리즘을 지원합니다.

  • dir
  • RSA-OAEP-256
  • A128KW, A192KW, A256KW
  • A128GCMKW, A192GCMKW, A256GCMKW
  • PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW
  • ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW

키 및 키 표현

JWS, 서명된 JWT, 암호화된 JWT 등을 아우르는 JOSE 표준에서는 암호화 키를 사용하여 정보에 서명하거나 암호화하는 방법을 설명합니다. 모든 암호화 작업의 기본 요소에는 알고리즘과 키가 포함됩니다. 알고리즘마다 다른 키 유형이 필요하며 경우에 따라 다른 키 크기가 필요합니다.

서명을 위한 HS* 계열 또는 암호화를 위한 A128KW 알고리즘과 같은 대칭 알고리즘에는 대칭 키 또는 공유 키가 필요합니다. 즉, 서명 및 확인에 동일한 키가 사용되거나 암호화 및 복호화에 동일한 키가 사용됩니다. 서명을 위한 RS*, PS*, ES* 알고리즘이나 암호화를 위한 ECDH* 알고리즘과 같은 비대칭 알고리즘은 키 쌍을 사용합니다. 공개 키와 비공개 키가 있고 이 두 키가 일치합니다. 서명할 때는 서명자는 비공개 키를 사용하여 서명하고, 모든 당사자가 공개 키를 사용하여 서명을 확인할 수 있습니다. 암호화할 때는 암호화 유틸리티가 공개 키를 사용하여 암호화하고 복호화 유틸리티가 비공개 키를 사용하여 복호화합니다. 공개 키는 이름에서 알 수 있듯이 공개적으로 공유할 수 있으므로 비밀로 유지할 필요가 없습니다.

암호화 키를 텍스트 형식으로 직렬화하는 방법에는 여러 가지가 있습니다. Apigee 정책은 다양한 형식으로 직렬화된 키를 허용합니다. 예를 들면 PEM 인코딩 형식, JWKS 형식, 공유 키의 경우 UTF-8 인코딩 또는 base64 인코딩 형식 등이 있습니다.

PEM 형식

공개 키 또는 비공개 키의 경우 IETF RFC 7468에 정의된 PEM 인코딩을 사용하는 것이 일반적입니다. 다음은 PEM 형식으로 표시되는 비공개 키의 예시입니다.

-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgVcB/UNPxalR9zDYAjQIf
jojUDiQuGnSJrFEEzZPT/92hRANCAASc7UJtgnF/abqWM60T3XNJEzBv5ez9TdwK
H0M6xpM2q+53wmsN/eYLdgtjgBd3DBmHtPilCkiFICXyaA8z9LkJ
-----END PRIVATE KEY-----

공개 키 또는 암호화된 비공개 키에 유사한 PEM 형식이 있습니다.

JWKS 형식

JSON 웹 키(JWK)는 단일 암호화 키를 나타내는 JSON 데이터 구조입니다. JSON 웹 키 세트(JWKS)는 JWK 세트를 나타내는 JSON 구조입니다. JWK와 JWKS는 RFC7517에 설명되어 있습니다. JWKS 예시는 부록 A. JSON 웹 키 세트 예시를 참조하세요.

JWKS는 모든 당사자가 표준 형식으로 키 세트를 나타낼 수 있도록 하기 위한 것입니다. 주요 사용 사례는 JWKS 형식으로 데이터를 전달하는 HTTP 엔드포인트를 통해 표준 방식으로 공개 키를 공유하는 것입니다. ID 공급업체와 같이 서명된 JWS 또는 JWT를 생성하는 회사 또는 시스템이 공개 키를 게시하면 공개 키를 읽을 수 있는 모든 시스템 또는 애플리케이션이 서명 당사자가 생성한 서명을 확인할 수 있습니다. 반대로 특정 당사자 또는 회사에서만 읽어야 하는 데이터를 암호화하려는 모든 시스템 또는 앱은 해당 당사자 또는 회사에 속한 공개 키를 검색하고 해당 목적을 위해 암호화된 JWT를 생성할 수 있습니다.

RFC7517RSA 또는 EC와 같은 각 키 유형의 JWKS 키 요소를 설명합니다. 다음 요소는 항상 있어야 합니다.

  • kty - 키 유형(예: RSA 또는 EC)
  • kid - 키 ID. 임의의 고유 문자열 값일 수 있습니다. 단일 키 세트 내에 중복이 없어야 합니다. 인바운드 JWT가 JWKS 세트에 있는 키 ID를 보유하는 경우 VerifyJWS 또는 VerifyJWT 정책은 올바른 공개 키를 사용하여 JWS/JWT 서명을 인증합니다.

다음은 선택적 요소와 해당 값의 예시입니다.

  • alg: 키 알고리즘. JWS/JWT의 서명 알고리즘과 일치해야 합니다.
  • use: 키의 의도된 용도. 일반적인 값은 서명 및 확인의 경우 'sig', 암호화 및 복호화의 경우 'enc'입니다.

다음 JWKS(원래 https://www.googleapis.com/oauth2/v3/certs에서 검색되었지만 지금은 최신 상태가 아님)에 필수 요소와 값이 포함되어 있으며 Apigee에서 사용할 수 있습니다.

{
     "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",
        }
     ]
  }
  

JWS 및 JWT 정책에 키 지정

JWS 또는 JWT를 생성하거나 검증하는 경우 암호화 작업에서 사용할 키를 제공해야 합니다.

서명된 JWT를 생성할 때는 서명을 생성할 수 있는 키를 제공해야 합니다.

  • 비대칭 키를 사용하는 RS*, PS* 또는 ES* 서명 알고리즘의 경우 모두 서명을 생성하기 위해 비공개 키를 제공해야 합니다.
  • HS* 알고리즘의 경우 서명을 생성할 때 사용할 대칭 키를 제공해야 합니다.

서명된 JWS/JWT를 확인할 때는 서명을 확인할 수 있는 키를 제공해야 합니다.

  • RS*, PS* 또는 ES* 서명 알고리즘의 경우 원래 토큰에 서명하는 데 사용된 비공개 키와 연결된 공개 키를 제공해야 합니다.
  • HS* 알고리즘의 경우 JWS 또는 JWT에 서명하는 데 사용된 것과 동일한 대칭 키를 제공해야 합니다.

JWS 및 JWT 정책에 키를 제공하는 옵션으로는 다음 두 가지가 있습니다.

  • 일반적으로 컨텍스트 변수를 통해 직접적으로 키 제공
  • kid 및 JWKS를 통해 간접적으로 키 제공 Apigee가 JWKS를 검색할 수 있는 HTTP URL을 통해 JWKS를 직접 또는 간접적으로 지정할 수 있습니다.

JWKS URL은 대개 공개 상태이므로 JWKS URL 옵션은 일반적으로 비대칭 알고리즘에 사용할 수 있는 공개 키의 소스로만 사용됩니다.

다음 예시는 다양한 시나리오에서 키를 직접 제공하는 방법을 보여줍니다.

  • HS256 알고리즘으로 서명된 JWT를 생성합니다. 이 경우 필요한 키는 대칭 키입니다. 이 정책은 base64url로 인코딩된 보안 비밀 키가 포함된 컨텍스트 변수를 제공합니다.

    <GenerateJWT name='gen-138'>
      <Algorithm>HS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <SecretKey encoding='base64url'>
        <Value ref='private.secretkey'/>
        <Id ref='variable-containing-desired-keyid'/>
      </SecretKey>
      . . .
      <OutputVariable>output_variable_name</OutputVariable>
    </GenerateJWT>
  • HS256 알고리즘으로 서명된 JWT를 확인합니다. 이 경우 필요한 키는 대칭 키입니다. 위의 예시에서와 같이 이 정책은 base64url로 인코딩된 보안 비밀 키가 포함된 컨텍스트 변수를 제공합니다.

    <VerifyJWT name='verify-138'>
      <Algorithm>HS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <SecretKey encoding='base64url'>
        <Value ref='private.secretkey'/>
      </SecretKey>
      . . .
      <OutputVariable>output_variable_name</OutputVariable>
    </VerifyJWT>
  • PS256 알고리즘으로 서명된 JWT를 확인합니다. 이 경우 필요한 키는 공개 RSA 키입니다. 이 정책은 PEM으로 인코딩된 공개 키가 포함된 컨텍스트 변수를 제공합니다.

    <VerifyJWT name='JWT-001'>
      <Algorithm>PS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
        <Value ref='variable-containing-pem-encoded-public-key'/>
      </PublicKey>
      . . .
    </VerifyJWT>
  • PS256 알고리즘으로 서명된 JWT를 생성됩니다. 이 경우 필요한 키는 비공개 RSA 키입니다. 이 정책은 PEM으로 인코딩된 비공개 키가 포함된 컨텍스트 변수를 제공합니다.

    <GenerateJWT name='JWT-002'>
      <Algorithm>PS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PrivateKey>
        <Value ref='private.variable-containing-pem-encoded-private-key'/>
      </PrivateKey>
       . . .
    </GenerateJWT>

JWS 또는 서명된 JWT 확인 시 JWKS를 키 소스로 사용

시스템 또는 앱에서 JWS/JWT를 생성할 때 일반적으로 시스템 또는 앱은 JWS/JWT 헤더에 키 식별자(kid 클레임)를 삽입합니다. 이 키는 JWS/JWT 리더에게 서명된 JWS/JWT에서 서명을 확인하거나 암호화된 JWT를 복호화하는 데 필요한 키를 알려줍니다.

예를 들어 발급기관이 비공개 키로 JWT에 서명한다고 가정합니다. '키 ID'는 JWT를 확인하는 데 사용해야 하는 일치하는 공개 키를 식별합니다. 공개 키 목록은 일반적으로 Google ID 엔드포인트 또는 Firebase 인증 엔드포인트와 같이 잘 알려진 엔드포인트에서 사용할 수 있습니다. 다른 제공업체는 JWKS 형식으로 키를 게시하는 자체 공개 엔드포인트를 갖게 됩니다.

JWKS 엔드포인트를 통해 공유되는 공개 키로 JWS 또는 서명된 JWT를 확인하기 위해 Apigee를 사용하는 경우 몇 가지 옵션을 사용할 수 있습니다.

  • 옵션 1: 정책 구성에서 <PublicKey/JWKS> 요소에 JWKS 엔드포인트 URI를 지정합니다. 예를 들어 VerifyJWT 정책의 경우 다음과 같습니다.

    <VerifyJWT name="JWT-Verify-RS256">
      <Algorithm>RS256</Algorithm>
      <Source>json.jwt</Source>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
          <JWKS uri="https://www.googleapis.com/oauth2/v3/certs"/>
      </PublicKey>
      . . .
    </VerifyJWT>
    

    이 경우 Apigee는 다음을 수행합니다.

    1. JWS/JWT 헤더를 검사하여 RS256과 같은 서명 알고리즘(alg)을 찾고 해당 알고리즘이 정책에 구성된 알고리즘과 일치하지 않으면 인바운드 JWT를 거부합니다.
    2. 지정된 JWKS 엔드포인트에서 또는 이 JWKS 엔드포인트가 이전에 사용된 적이 있으면 내부 캐시에서 해당 ID가 있는 키 목록을 검색합니다.
    3. JWS/JWT 헤더를 검사하여 키 ID(kid)를 찾습니다. 인바운드 JWT가 헤더에 키 ID(kid)를 포함하지 않으면 하위 항목을 확인 키에 매핑할 수 없으며 Apigee에서 오류를 발생시킵니다.
    4. JWS/JWT 헤더에 명시된 키 ID가 있는 JWK를 JWKS에서 추출합니다. 해당 키 ID를 가진 키가 없으면 오류가 발생합니다.
    5. JWK의 알고리즘이 정책 구성에 지정된 알고리즘과 일치하는지 확인합니다. 알고리즘이 일치하지 않으면 확인을 거부하고 오류가 발생합니다.
    6. 이 공개 키를 사용하여 JWS/JWT의 서명을 확인합니다. 서명이 확인되지 않으면 확인을 거부하고 오류가 발생합니다.
  • 옵션 2: 정책 구성에서 <PublicKey/JWKS> 요소에 JWKS 엔드포인트 URI를 저장하는 변수를 지정합니다.

    예를 들어 VerifyJWT 정책의 경우 다음과 같습니다.

    <VerifyJWT name="JWT-Verify-RS256">
      <Algorithm>RS256</Algorithm>
      <Source>json.jwt</Source>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
        <JWKS uriRef="variable-containing-a-uri"/>
      </PublicKey>
      . . .
    </VerifyJWT>
    

    이 경우 Apigee는 위와 동일한 단계를 수행하지만, 하드 코딩된 URI가 아니라 uriRef 속성에서 참조된 변수에 지정된 URI에서 JWKS를 검색한다는 점이 다릅니다. 캐싱은 여전히 적용됩니다.

  • 옵션 3: 정책 구성에서 <PublicKey/JWKS> 요소에 하드 코딩된 JWKS 데이터를 저장하는 변수를 지정합니다.

    예를 들어 VerifyJWT 정책의 경우 다음과 같습니다.

    <VerifyJWT name="JWT-Verify-RS256">
      <Algorithm>RS256</Algorithm>
      <Source>json.jwt</Source>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
        <JWKS ref="variable-that-holds-a-jwks"/>
      </PublicKey>
      . . .
    </VerifyJWT>
    

    이 경우 Apigee는 위와 동일한 단계를 수행하지만, URI가 아닌 ref 속성에 지정한 컨텍스트 변수에서 JWKS를 검색한다는 점이 다릅니다. 일반적으로 이 컨텍스트 변수는 ServiceCallout, KVM 또는 프록시에 연결된 속성 파일에서 로드했을 것입니다.

암호화된 JWT 생성 시 JWKS를 키 소스로 사용

비대칭 알고리즘(RSA-OAEP-256 또는 ECDH-* 변형)을 통해 암호화된 JWT를 생성할 때는 공개 키를 사용하여 암호화합니다. GenerateJWT 정책에 키를 제공할 수 있는 옵션이 있습니다.

일반적인 방법은 정책 구성에 <PublicKey/JWKS> 요소의 JWKS 엔드포인트 URI를 지정하는 것입니다. 예를 들면 다음과 같습니다.

<GenerateJWT name="GJWT-1">
  <Algorithms>
    <Key>RSA-OAEP-256</Key>
    <Content>A128GCM</Content>
  </Algorithms>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <PublicKey>
    <JWKS uri='https://www.example.com/.well-known/jwks.json'/>
    <Id ref='variable-containing-desired-keyid'/>
  </PublicKey>
    . . .
</GenerateJWT>

이 경우 Apigee는 다음을 수행합니다.

  1. 정책 구성에 따라 JWT의 인코딩되지 않은 페이로드와 헤더를 조합합니다.
  2. 지정된 JWKS 엔드포인트에서 또는 이 JWKS 엔드포인트가 이전에 사용된 적이 있으면 내부 캐시에서 해당 ID가 있는 키 목록을 검색합니다. 현재 캐시 TTL은 5분입니다.
  3. JWKS에서 PublicKey/Id 요소에 명시된 키 ID가 있는 JWK를 추출합니다. 해당 키 ID를 가진 키가 없으면 오류가 발생합니다.
  4. JWK의 알고리즘이 정책 구성에 지정된 알고리즘과 일치하는지 확인합니다. 알고리즘이 일치하지 않으면 오류가 발생합니다.
  5. 콘텐츠 암호화 키로 사용할 무작위 시퀀스를 생성합니다.
  6. 선택한 공개 키를 사용하여 콘텐츠 암호화 키를 암호화합니다.
  7. 콘텐츠 암호화 키를 사용하여 페이로드를 암호화합니다.
  8. 마지막으로 모든 부분을 직렬화된 암호화된 JWT로 조합합니다.

대안은 uriRef 속성을 사용하여 JWKS 엔드포인트의 URI를 포함하는 변수를 지정하는 것입니다. 예를 들면 다음과 같습니다.

<GenerateJWT name="GJWT-1">
  <Algorithms>
    <Key>RSA-OAEP-256</Key>
    <Content>A128GCM</Content>
  </Algorithms>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <PublicKey>
    <JWKS uriRef='variable-containing-jwks-uri'/>
    <Id ref='variable-containing-desired-keyid'/>
  </PublicKey>
  . . .
</GenerateJWT>

이 경우 Apigee는 위와 동일한 단계를 수행하지만, 하드 코딩된 URI가 아니라 uriRef 속성에서 참조된 변수에 지정된 URI에서 JWKS를 검색한다는 점이 다릅니다. 이 JWKS 엔드포인트가 이전에 사용된 적이 있으면 Apigee는 내부 캐시에서 JWKS를 읽습니다.