Vista geral das políticas JWS e JWT

Esta página aplica-se ao Apigee e ao Apigee Hybrid.

Veja a documentação do Apigee Edge.

Este tópico fornece informações gerais sobre o JWT (símbolo da Web JSON) e o JWS (assinatura Web JSON) e as políticas de JWS/JWT do Apigee que podem ser do interesse dos programadores de proxy do Apigee.

Introdução

O JWS e o JWT são usados frequentemente para partilhar reivindicações ou afirmações entre aplicações ligadas. As políticas JWS/JWT permitem que os proxies de API do Apigee:

Nos dois últimos casos, a política também define variáveis de fluxo. Isto permite que as políticas subsequentes no fluxo do Apigee inspecionem as reivindicações no JWT ou JWS e tomem decisões com base nessas reivindicações ou propaguem essas informações para os serviços de back-end.

Quando usar as políticas VerifyJWS ou VerifyJWT, um JWS/JWT inválido é rejeitado e resulta numa condição de erro. Da mesma forma, quando usar as políticas DecodeJWS ou DecodeJWT, um JWS/JWT com formato incorreto resulta numa condição de erro.

Vídeos

Veja um breve vídeo para uma introdução rápida ao JWT. Embora este vídeo seja específico para gerar um JWT, muitos dos conceitos são os mesmos para JWS.

Um vídeo curto para saber mais sobre a estrutura JWT.

Exemplos de utilização

Pode usar as políticas JWS/JWT para:

  • Gere um novo JWS/JWT no proxy ou nos lados do ponto final de destino de um proxy do Apigee. Por exemplo, pode criar um fluxo de pedidos de proxy que gere um JWS/JWT e o devolva a um cliente. Em alternativa, pode conceber um proxy para que gere um JWS/JWT no fluxo de pedidos de destino e o anexe ao pedido enviado para o destino. O JWS/JWT e as respetivas reivindicações ficam, então, disponíveis para permitir que os serviços de back-end apliquem um processamento de segurança adicional.
  • Validar e extrair reivindicações de um JWS/JWT obtido a partir de pedidos de clientes de entrada, de respostas de serviços de destino, de respostas de políticas de chamadas de serviços ou de outras fontes. Para um JWS/JWT assinado, o Apigee usa um dos algoritmos RSA, ECDSA ou HMAC para validar a assinatura, quer o JWS/JWT tenha sido gerado pelo Apigee ou por terceiros. Para um JWT encriptado, o Apigee desencripta o JWT através de um dos algoritmos de encriptação JWA suportados (consulte a norma IETF RFC 7518).
  • Descodificar um JWS/JWT. A descodificação é mais útil quando usada em conjunto com a política Validar JWS/JWT, nos casos em que o valor de uma reivindicação (JWT) ou de um cabeçalho (JWS/JWT) no JWS/JWT tem de ser conhecido antes de validar um JWS/JWT assinado ou desencriptar um JWT encriptado.

Partes de um JWS/JWT

Um JWS/JWT assinado codifica informações em três partes separadas por pontos:

Header.Payload.Signature
  • A política Generate JWS/JWT cria todas as três partes.
  • A política Verify JWS/JWT examina todas as três partes.
  • A política DecodeJWS examina apenas o cabeçalho. A política DecodeJWT examina apenas o cabeçalho e o payload.

Um JWS também suporta um formulário separado que omite o payload do JWS:

Header..Signature

Com um JWS separado, a carga útil é enviada separadamente do JWS. Use o elemento <DetachedContent> da política Verify JWS para especificar a carga útil JWS não codificada. Em seguida, a política Verify JWS valida o JWS através do cabeçalho e da assinatura no JWS e da carga útil especificada pelo elemento <DetachedContent>.

Um JWT encriptado codifica informações em cinco partes separadas por pontos:

Header.Key.InitializationVector.Payload.AuthenticationTag

As políticas GenerateJWT e VerifyJWT criam ou examinam todas essas partes. O DecodeJWT só pode examinar o cabeçalho não encriptado.

Para saber mais sobre os tokens e como são codificados, assinados ou encriptados, consulte os documentos de normas relevantes:

Diferenças entre JWS e JWT

Pode usar um JWT ou um JWS para partilhar reivindicações ou afirmações entre aplicações ligadas. A principal diferença entre os dois é a representação da carga útil:

  • JWT
    • O payload é sempre um objeto JSON.
    • A carga útil está sempre anexada ao JWT.
    • O cabeçalho typ do token está sempre definido como JWT.
    • A carga útil pode ser assinada ou encriptada.
  • JWS
    • O payload pode ser representado por qualquer formato, como um objeto JSON, uma stream de bytes, uma stream de octetos e outros.
    • A carga útil não tem de estar anexada ao JWS.
    • O cabeçalho e o payload são sempre assinados. O JWS não suporta encriptação.

Uma vez que o formato JWT usa sempre um objeto JSON para representar o payload, as políticas GenerateJWT e VerifyJWT do Apigee têm suporte incorporado para processar nomes de reivindicações registadas comuns, como aud, iss, sub e outros. Isto significa que pode usar elementos da política GenerateJWT para definir estas reivindicações no payload e elementos da política VerifyJWT para verificar os respetivos valores. Consulte a secção Nomes de reivindicações registadas da especificação JWT para mais informações.

Além de suportar determinados Registered Claim Names, a política GenerateJWT suporta diretamente a adição de reivindicações com nomes arbitrários ao payload ou ao cabeçalho do JWT. Cada reivindicação é um simples par nome/valor, em que o valor pode ser do tipo number, boolean, string, map ou array.

Quando usa GenerateJWS, fornece uma variável de contexto que representa a carga útil. Uma vez que um JWS pode usar qualquer representação de dados para a carga útil, não existe o conceito de "afirmação de carga útil" num JWS, e a política GenerateJWS não suporta a adição de afirmações com nomes arbitrários à carga útil. É possível usar a política GenerateJWS para adicionar reivindicações com nomes arbitrários ao cabeçalho do JWS. Além disso, as políticas de JWS suportam um payload separado, em que o JWS omite o payload. Uma carga útil separada permite-lhe enviar o JWS e a carga útil separadamente. A utilização de uma carga útil separada pode ser mais eficiente em termos de espaço, especialmente para cargas úteis grandes, e é exigida por várias normas de segurança.

Assinatura vs. encriptação

O Apigee pode gerar JWTs assinados ou encriptados. Escolha JWT assinado quando a carga útil não precisar de ser secreta, mas for importante oferecer garantias de integridade e não repúdio aos leitores. Um JWT assinado garante aos leitores que a carga útil não foi alterada desde que o JWT foi assinado e que o JWT foi assinado pelo detentor da chave privada. Escolha JWT encriptado quando a carga útil deve ser secreta. Um JWT encriptado oferece confidencialidade para a carga útil, uma vez que apenas o detentor da chave adequada a pode desencriptar.

É possível usar JWTs encriptados e assinados em conjunto, especialmente quando o JWT encriptado usa um algoritmo de criptografia assimétrica (RSA, ECDSA). Nesse caso, não é possível determinar a identidade do produtor desse JWT, porque a chave de encriptação é pública. Para resolver esse problema, combine a assinatura com a encriptação. Um padrão típico é o seguinte:

  • Assine uma carga útil para produzir um JWS ou um JWT assinado.
  • Encriptar o resultado assinado para produzir um JWT encriptado.

Incorporar uma carga útil assinada num JWT encriptado através desta abordagem oferece garantias de não repúdio e confidencialidade. As políticas do Apigee podem produzir e descodificar e validar essas combinações.

Algoritmos de assinatura

Para JWT assinado, as políticas de validação de JWS/JWT e geração de JWS/JWT suportam algoritmos RSA, RSASSA-PSS, ECDSA e HMAC, usando somas de verificação SHA2 de intensidade de bits 256, 384 ou 512. As políticas DecodeJWS e DecodeJWT funcionam independentemente do algoritmo usado para assinar o JWS/JWT.

Algoritmos HMAC

Os algoritmos HMAC baseiam-se num segredo partilhado, conhecido como chave secreta, para criar a assinatura (também conhecida como assinatura do JWS/JWT) e para validar a assinatura.

O comprimento mínimo da chave secreta depende da intensidade de bits do algoritmo:

  • HS256: comprimento mínimo da chave de 32 bytes
  • HS384: comprimento mínimo da chave de 48 bytes
  • HS512: comprimento mínimo da chave de 64 bytes

Algoritmos RSA

Os algoritmos RSA usam um par de chaves pública/privada para a assinatura criptográfica. A especificação JWA usa os identificadores RS256, RS384 e RS512 para representar estas opções. Com as assinaturas RSA, a parte que assina usa uma chave privada RSA para assinar o JWS/JWT, e a parte que valida usa a chave pública RSA correspondente para validar a assinatura no JWS/JWT. Não existem requisitos de tamanho para as chaves.

Algoritmos RSASSA-PSS

Os algoritmos RSASSA-PSS são uma atualização dos algoritmos RSA e usam os identificadores PS256, PS384 e PS512. Tal como as variantes RS*, o RSASSA-PSS usa um par de chaves pública/privada RSA para a assinatura criptográfica. O formato, o mecanismo e os limites de tamanho da chave são os mesmos que para os algoritmos RS*.

Algoritmos ECDSA

O conjunto de algoritmos do algoritmo de assinatura digital de curva elíptica (ECDSA) são algoritmos de criptografia de curva elíptica com uma curva P-256, P-384 ou P-521. Quando usa algoritmos ECDSA, o algoritmo determina o tipo de chave pública e privada que tem de especificar:

Algoritmo Curva Requisito de chave
ES256 P-256 Uma chave gerada a partir da curva P-256 (também conhecida como secp256r1 ou prime256v1)
ES384 P-384 Uma chave gerada a partir da curva P-384 (também conhecida como secp384r1)
ES512 P-521 Uma chave gerada a partir da curva P-521 (também conhecida como secp521r1)

Algoritmos de encriptação

Quando usar GenerateJWT e VerifyJWT para processar JWT encriptados, as políticas suportam os seguintes algoritmos:

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

Chaves e representações de chaves

As normas JOSE, que abrangem JWS, JWT assinado e encriptado, e muito mais, descrevem como usar chaves criptográficas para assinar ou encriptar informações. Os elementos fundamentais de qualquer operação criptográfica incluem o algoritmo e a chave. Os diferentes algoritmos requerem diferentes tipos de chaves e, em alguns casos, diferentes tamanhos de chaves.

Os algoritmos simétricos, como a família HS* para assinatura ou o algoritmo A128KW para encriptação, requerem chaves simétricas ou partilhadas: a mesma chave é usada para assinar e verificar, ou a mesma chave é usada para encriptar e desencriptar. Os algoritmos assimétricos, como os algoritmos RS*, PS* e ES* para assinatura, ou os algoritmos ECDH* para encriptação, usam pares de chaves. Existe uma chave pública e uma chave privada, e estas são correspondentes. Na assinatura, o signatário usa a chave privada para assinar, e qualquer parte pode usar a chave pública para validar a assinatura. Na encriptação, o encriptador usa a chave pública para encriptar e o desencriptador usa a chave privada para desencriptar. As chaves públicas, como o nome sugere, podem ser partilhadas publicamente e não têm de ser mantidas em segredo.

Existem diferentes formas de serializar chaves criptográficas em formato de texto. As políticas do Apigee aceitam chaves serializadas de várias formas: formato codificado em PEM, formato JWKS ou, para chaves partilhadas, formato codificado em UTF-8 ou formato codificado em base64.

Formato PEM

Para chaves públicas ou privadas, é comum usar a codificação PEM, que é definida no IETF RFC 7468. Segue-se um exemplo de uma chave privada representada no formato PEM:

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

Existem formatos PEM semelhantes para chaves públicas ou chaves privadas encriptadas.

Formato JWKS

Uma chave Web JSON (JWK) é uma estrutura de dados JSON que representa uma única chave criptográfica. Um conjunto de chaves Web JSON (JWKS) é uma estrutura JSON que representa um conjunto de JWKs. O JWK e o JWKS são descritos no RFC7517. Veja exemplos de JWKS no Apêndice A. Exemplo de chave Web JSON Sets.

O JWKS destina-se a permitir que qualquer parte represente um conjunto de chaves num formato padrão. Um exemplo de utilização importante é a partilha de chaves públicas de forma padrão, através de um ponto final HTTP que fornece dados no formato JWKS. Quando uma empresa ou um sistema que gera JWS ou JWT assinados, como um fornecedor de identidade, publica as respetivas chaves públicas, qualquer sistema ou aplicação que possa ler as chaves públicas pode validar as assinaturas geradas pela parte signatária. Por outro lado, qualquer sistema ou app que queira encriptar dados que devem ser lidos apenas por uma determinada parte ou empresa, pode obter as chaves públicas pertencentes a essa parte ou empresa e gerar um JWT encriptado para esse fim.

A RFC7517 descreve os elementos principais da chave JWKS para cada tipo de chave, como RSA ou EC. Estes elementos devem estar sempre presentes:

  • kty: o tipo de chave, como RSA ou EC.
  • kid: o ID da chave. Este pode ser qualquer valor de string exclusivo arbitrário; não devem existir duplicados num único conjunto de chaves. Se o JWT de entrada tiver um ID da chave que esteja presente no conjunto de JWKS, a política VerifyJWS ou VerifyJWT usa a chave pública correta para validar a assinatura JWS/JWT.

Seguem-se exemplos de elementos opcionais e os respetivos valores:

  • alg: o algoritmo da chave. Tem de corresponder ao algoritmo de assinatura no JWS/JWT.
  • use: a utilização prevista da chave. Os valores típicos são "sig" para assinatura e validação, ou "enc" para encriptação e desencriptação.

O seguinte JWKS (originalmente obtido a partir de https://www.googleapis.com/oauth2/v3/certs, mas agora desatualizado) inclui os elementos e os valores necessários e seria utilizável pelo 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",
        }
     ]
  }
  

Especificar chaves para as políticas JWS e JWT

Quer esteja a gerar ou a validar JWS ou JWT, tem de fornecer uma chave para utilização nas operações criptográficas.

Quando gera um JWT assinado, tem de fornecer uma chave que possa produzir a assinatura.

  • No caso de um algoritmo de assinatura RS*, PS* ou ES*, que usa chaves assimétricas, tem de fornecer a chave privada para gerar a assinatura.
  • No caso de um algoritmo HS*, tem de fornecer a chave simétrica que vai ser usada quando gerar a assinatura.

Quando valida um JWS/JWT assinado, tem de fornecer uma chave que possa validar a assinatura.

  • No caso de um algoritmo de assinatura RS*, PS* ou ES*, tem de fornecer a chave pública associada à chave privada que foi originalmente usada para assinar o token.
  • No caso de um algoritmo HS*, tem de fornecer a mesma chave simétrica que foi usada para assinar o JWS ou o JWT.

Tem duas opções para fornecer as chaves às políticas JWS e JWT:

  • Fornecer o valor da chave diretamente (normalmente através de uma variável de contexto) ou
  • Fornecer a chave indiretamente, através de um kid e um JWKS. Pode especificar o JWKS diretamente ou indiretamente através de um URL http no qual o Apigee pode obter o JWKS.

A opção de URL JWKS é normalmente usada apenas como uma origem de chaves públicas que são utilizáveis com algoritmos assimétricos, porque os URLs JWKS são normalmente públicos.

Os exemplos seguintes ilustram formas de fornecer chaves diretamente em vários cenários.

  • Gere um JWT assinado com o algoritmo HS256. A chave necessária neste caso é uma chave simétrica. Esta política fornece uma variável de contexto que contém a chave secreta codificada em 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>
  • Valide um JWT assinado com o algoritmo HS256. A chave necessária neste caso é uma chave simétrica. Tal como no exemplo acima, esta política fornece uma variável de contexto que contém a chave secreta codificada em 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>
  • Valide um JWT que tenha sido assinado com o algoritmo PS256. A chave necessária neste caso é uma chave RSA pública. Esta política fornece uma variável de contexto que contém a chave pública codificada em PEM.

    <VerifyJWT name='JWT-001'>
      <Algorithm>PS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
        <Value ref='variable-containing-pem-encoded-public-key'/>
      </PublicKey>
      . . .
    </VerifyJWT>
  • Gere um JWT assinado com o algoritmo PS256. A chave necessária neste caso é uma chave RSA privada. Esta política fornece uma variável de contexto que contém a chave privada codificada em PEM.

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

JWKS como origem de chaves ao validar um JWS ou um JWT assinado

Quando um sistema ou uma app gera um JWS/JWT, normalmente, o sistema ou a app insere um identificador de chave (a reivindicação kid) no cabeçalho do JWS/JWT. A chave indica a qualquer leitor do JWS/JWT que chave é necessária para validar a assinatura no JWS/JWT assinado ou desencriptar o JWT encriptado.

Por exemplo, suponhamos que um emissor assina um JWT com uma chave privada. O "Key ID" identifica a chave pública correspondente que tem de ser usada para validar o JWT. Normalmente, a lista de chaves públicas está disponível num ponto final conhecido, como o ponto final da Google Identity ou o ponto final do Firebase Authentication. Outros fornecedores têm os seus próprios pontos finais públicos que publicam chaves no formato JWKS.

Quando usa o Apigee para validar um JWS ou um JWT assinado com chaves públicas partilhadas através de um ponto final JWKS, tem algumas opções:

  • Opção 1: na configuração da política, especifique o URI do ponto final JWKS no elemento <PublicKey/JWKS>. Por exemplo, para a política 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>

    Neste caso, o Apigee:

    1. Examine o cabeçalho JWS/JWT para encontrar o algoritmo de assinatura (alg), como RS256, e rejeite o JWT de entrada se esse algoritmo não corresponder ao algoritmo configurado na política.
    2. Obter a lista de chaves com os respetivos IDs do ponto final JWKS especificado ou de uma cache interna se este ponto final JWKS tiver sido usado anteriormente.
    3. Examine o cabeçalho JWS/JWT para encontrar o ID da chave (kid). Se o JWT de entrada não incluir um ID da chave (kid) no cabeçalho, o mapeamento do kid para a chave de validação não é possível e o Apigee gera uma falha.
    4. Extraia do JWKS o JWK com o ID da chave indicado no cabeçalho JWS/JWT. Gera uma falha se não existir uma chave com esse ID de chave.
    5. Verifique se o algoritmo para o JWK corresponde ao algoritmo especificado na configuração da política. Rejeite a validação e apresente uma falha se os algoritmos não corresponderem.
    6. Use essa chave pública para validar a assinatura no JWS/JWT. Rejeitar a validação e gerar uma falha se a assinatura não for validada.
  • Opção 2: na configuração da política, especifique uma variável que contenha o URI do ponto final JWKS no elemento <PublicKey/JWKS>.

    Por exemplo, para a política 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>

    Neste caso, o Apigee executa os mesmos passos que acima, exceto que o Apigee obtém o JWKS não de um URI codificado, mas do URI especificado na variável referenciada pelo atributo uriRef. O armazenamento em cache continua a aplicar-se.

  • Opção 3: na configuração da política, especifique uma variável que contenha os dados JWKS codificados no elemento <PublicKey/JWKS>.

    Por exemplo, para a política 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>

    Neste caso, o Apigee executa os mesmos passos que acima, exceto que o Apigee obtém o JWKS não a partir de um URI, mas da variável de contexto que especifica no atributo ref. Normalmente, teria carregado esta variável de contexto a partir de um ServiceCallout, um KVM ou um ficheiro de propriedades associado ao proxy.

JWKS como origem de chaves ao gerar um JWT encriptado

Quando gera um JWT encriptado através de um algoritmo assimétrico (RSA-OAEP-256 ou qualquer uma das variantes ECDH-*), usa a chave pública para encriptar. Tem opções para fornecer a chave à política GenerateJWT

Uma abordagem típica consiste em especificar na configuração da política o URI do ponto final JWKS no elemento <PublicKey/JWKS>. Por exemplo:

<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>

Neste caso, o Apigee:

  1. Reúna o payload não codificado e o cabeçalho do JWT com base na configuração da política.
  2. Obter a lista de chaves com os respetivos IDs do ponto final JWKS especificado ou de uma cache interna se este ponto final JWKS tiver sido usado anteriormente. Atualmente, o TTL da cache é de 5 minutos.
  3. Extraia o JWK com o ID da chave indicado no elemento PublicKey/Id do JWKS. Gera uma falha se não existir uma chave com esse ID de chave.
  4. Verifique se o algoritmo para o JWK corresponde ao algoritmo especificado na configuração da política. Throw a fault if the algorithms do not match.
  5. Gerar uma sequência aleatória a usar como chave de encriptação de conteúdo.
  6. Use a chave pública selecionada para encriptar a chave de encriptação de conteúdo.
  7. Use a chave de encriptação de conteúdo para encriptar a carga útil.
  8. Por fim, junte todas as partes num JWT encriptado com número de série.

Em alternativa, pode usar o atributo uriRef para especificar uma variável que contenha o URI de um ponto final JWKS. Por exemplo:

<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>

Neste caso, o Apigee executa os mesmos passos que acima, exceto que o Apigee obtém o JWKS do URI especificado na variável referenciada pelo atributo uriRef, em vez de um URI codificado. O Apigee lê o JWKS a partir de uma cache interna se este ponto final JWKS tiver sido usado anteriormente.