Panoramica dei criteri JWS e JWT

Questa pagina si applica ad Apigee e Apigee hybrid.

Visualizza la documentazione di Apigee Edge.

Questo argomento fornisce informazioni generali su JWT (JSON Web Token) e JWS (JSON Web Signature) e sui criteri JWS/JWT di Apigee che potrebbero essere di interesse per gli sviluppatori di proxy Apigee.

Introduzione

JWS e JWT vengono comunemente utilizzati per condividere rivendicazioni o affermazioni tra applicazioni collegate. I criteri JWS/JWT consentono ai proxy API Apigee di:

Nei due casi più recenti, il criterio imposta anche le variabili di flusso. In questo modo, i criteri successivi nel flusso Apigee possono ispezionare i claim nel JWT o JWS e prendere decisioni in base a questi claim o propagare queste informazioni ai servizi di backend.

Quando utilizzi i criteri VerifyJWS o VerifyJWT, un JWS/JWT non valido verrà rifiutato e verrà generata una condizione di errore. Analogamente, quando utilizzi i criteri DecodeJWS o DecodeJWT, un JWS/JWT con formato non corretto comporterà una condizione di errore.

Video

Guarda un breve video per una rapida introduzione ai token JWT. Anche se questo video riguarda specificamente la generazione di un JWT, molti dei concetti sono gli stessi per i JWS.

Un breve video per scoprire di più sulla struttura JWT.

Casi d'uso

Puoi utilizzare i criteri JWS/JWT per:

  • Genera un nuovo JWS/JWT sul lato del proxy o dell'endpoint di destinazione di un proxy Apigee. Ad esempio, puoi creare un flusso di richieste proxy che genera un JWS/JWT e lo restituisce a un client. In alternativa, puoi progettare un proxy in modo che generi un JWS/JWT nel flusso di richieste di destinazione e lo aggiunga alla richiesta inviata al target. JWS/JWT e i relativi claim saranno quindi disponibili per consentire ai servizi di backend di applicare un'ulteriore elaborazione di sicurezza.
  • Verifica ed estrai i claim da un JWS/JWT ottenuto dalle richieste in entrata dei client, dalle risposte del servizio di destinazione, dalle risposte alle norme relative ai callout del servizio o da altre origini. Per un JWS/JWT firmato, Apigee utilizzerà uno degli algoritmi RSA, ECDSA o HMAC per verificare la firma, indipendentemente dal fatto che il JWS/JWT sia stato generato da Apigee o da terze parti. Per un JWT criptato, Apigee lo decripterà utilizzando uno degli algoritmi di crittografia JWA supportati (consulta IETF RFC 7518).
  • Decodifica un JWS/JWT. La decodifica è più utile se utilizzata in combinazione con il criterio di verifica JWS/JWT, nei casi in cui il valore di un claim (JWT) o di un'intestazione (JWS/JWT) all'interno del JWS/JWT deve essere conosciuto prima di verificare un JWS/JWT firmato o decriptare un JWT criptato.

Componenti di un JWS/JWT

Un JWS/JWT firmato codifica le informazioni in tre parti separate da puntini:

Header.Payload.Signature
  • Il criterio Genera JWS/JWT crea tutte e tre le parti.
  • Il criterio Verifica JWS/JWT esamina tutte e tre le parti.
  • Il criterio DecodeJWS esamina solo l'intestazione. Il criterio DecodeJWT esamina solo l'intestazione e il payload.

Un JWS supporta anche un modulo sganciato che omette il payload dal JWS:

Header..Signature

Con un JWS scollegato, il payload viene inviato separatamente dal JWS. Utilizza l'elemento <DetachedContent> del criterio Verifica JWS per specificare il payload JWS non codificato e non elaborato. Il criterio Verifica JWS verifica quindi il JWS utilizzando l'intestazione e la firma nel JWS e il payload specificato dall'elemento <DetachedContent>.

Un JWT criptato codifica le informazioni in cinque parti separate da punti:

Header.Key.InitializationVector.Payload.AuthenticationTag

I criteri GenerateJWT e VerifyJWT creano o esaminano tutte queste parti. DecodeJWT può esaminare solo l'intestazione non criptata.

Per scoprire di più sui token e su come vengono codificati, firmati o criptati, consulta i documenti degli standard pertinenti:

Differenze tra JWS e JWT

Puoi utilizzare un JWT o JWS per condividere rivendicazioni o affermazioni tra le applicazioni collegate. La principale differenza tra i due è la rappresentazione del payload:

  • JWT
    • Il payload è sempre un oggetto JSON.
    • Il payload è sempre allegato al JWT.
    • L'intestazione typ del token è sempre impostata su JWT.
    • Il payload può essere firmato o criptato.
  • JWS
    • Il payload può essere rappresentato da qualsiasi formato, ad esempio un oggetto JSON, uno stream di byte, uno stream di ottetti e altri.
    • Il payload non deve essere allegato al JWS.
    • L'intestazione e il payload sono sempre firmati. JWS non supporta la crittografia.

Poiché il formato JWT utilizza sempre un oggetto JSON per rappresentare il payload, i criteri Apigee GenerateJWT e VerifyJWT hanno il supporto integrato per gestire i nomi comuni dei claim registrati, come aud, iss, sub e altri. Ciò significa che puoi utilizzare gli elementi del criterio GenerateJWT per impostare questi claim nel payload e gli elementi del criterio VerifyJWT per verificarne i valori. Per saperne di più, consulta la sezione Nomi di rivendicazioni registrati della specifica JWT.

Oltre a supportare determinati nomi di claim registrati, il criterio GenerateJWT supporta direttamente l'aggiunta di claim con nomi arbitrari al payload o all'intestazione del JWT. Ogni claim è una semplice coppia nome/valore, in cui il valore può essere di tipo number, boolean, string, map o array.

Quando utilizzi GenerateJWS, fornisci una variabile di contesto che rappresenta il payload. Poiché un JWS può utilizzare qualsiasi rappresentazione di dati per il payload, non esiste il concetto di "claim del payload" in un JWS e il criterio GenerateJWS non supporta l'aggiunta di claim con nomi arbitrari al payload. È possibile utilizzare il criterio GenerateJWS per aggiungere claim con nomi arbitrari all'intestazione del JWS. Inoltre, i criteri JWS supportano un payload scollegato, in cui JWS omette il payload. Un payload scollegato ti consente di inviare il JWS e il payload separatamente. L'utilizzo di un payload scollegato può essere più efficiente in termini di spazio, in particolare per i payload di grandi dimensioni, ed è obbligatorio da diversi standard di sicurezza.

Firma e crittografia

Apigee può generare JWT firmati o criptati. Scegli JWT firmato quando il payload non deve essere segreto, ma è importante fornire ai lettori garanzie di integrità e non ripudio. Un JWT firmato garantisce ai lettori che il payload non è cambiato dal momento della firma del JWT e che il JWT è stato firmato dal proprietario della chiave privata. Scegli JWT criptato quando il payload deve essere segreto. Un JWT criptato garantisce la riservatezza del payload, in quanto solo il detentore della chiave appropriata può decriptarlo.

È possibile utilizzare contemporaneamente JWT criptati e firmati, in particolare quando il JWT criptato utilizza un algoritmo di crittografia asimmetrica (RSA, ECDSA). In questo caso, l'identità del produttore del JWT non può essere determinata, perché la chiave di crittografia è pubblica. Per risolvere il problema, combina la firma con la crittografia. Un pattern tipico è il seguente:

  • Firma un payload per produrre un JWS o un JWT firmato.
  • Crittografa il risultato firmato per produrre un JWT criptato.

L'inserimento di un payload firmato all'interno di un JWT criptato utilizzando questo approccio fornisce garanzie sia di non ripudio sia di riservatezza. I criteri Apigee possono produrre, decodificare e verificare queste combinazioni.

Algoritmi di firma

Per i JWT firmati, i criteri di verifica e generazione JWS/JWT supportano gli algoritmi RSA, RSASSA-PSS, ECDSA e HMAC, utilizzando le somme di controllo SHA2 con una potenza in bit di 256, 384 o 512. I criteri DecodeJWS e DecodeJWT funzionano indipendentemente dall'algoritmo utilizzato per firmare il JWS/JWT.

Algoritmi HMAC

Gli algoritmi HMAC si basano su un segreto condiviso, noto come chiave segreta, per creare la firma (nota anche come firma JWS/JWT) e per verificarla.

La lunghezza minima della chiave segreta dipende dalla potenza in bit dell'algoritmo:

  • HS256: lunghezza minima della chiave di 32 byte
  • HS384: lunghezza minima della chiave di 48 byte
  • HS512: lunghezza minima della chiave di 64 byte

Algoritmi RSA

Gli algoritmi RSA utilizzano una coppia di chiave pubblica/privata per la firma crittografica. La specifica JWA utilizza i moniker RS256, RS384 e RS512 per rappresentare queste opzioni. Con le firme RSA, la parte che esegue la firma utilizza una chiave privata RSA per firmare il JWS/JWT e la parte che esegue la verifica utilizza la chiave pubblica RSA corrispondente per verificare la firma sul JWS/JWT. Non esistono requisiti di dimensione per le chiavi.

Algoritmi RSASSA-PSS

Gli algoritmi RSASSA-PSS sono un aggiornamento degli algoritmi RSA e utilizzano i moniker PS256, PS384 e PS512. Come le varianti RS*, RSASSA-PSS utilizza una coppia di chiave pubblica/privata RSA per la firma crittografica. Il formato, il meccanismo e i limiti di dimensioni della chiave sono gli stessi per gli algoritmi RS*.

Algoritmi ECDSA

L'insieme di algoritmi ECDSA (Elliptic Curve Digital Signature Algorithm) sono algoritmi di crittografia ellittica con una curva P-256, P-384 o P-521. Quando utilizzi gli algoritmi ECDSA, l'algoritmo determina il tipo di chiave pubblica e privata da specificare:

Algoritmo Curve Requisito principale
ES256 P-256 Una chiave generata dalla curva P-256 (nota anche come secp256r1 o prime256v1)
ES384 P-384 Una chiave generata dalla curva P-384 (nota anche come secp384r1)
ES512 P-521 Una chiave generata dalla curva P-521 (nota anche come secp521r1)

Algoritmi di crittografia

Quando utilizzi GenerateJWT e VerifyJWT per gestire i JWT criptati, i criteri supportano i seguenti algoritmi:

  • 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

Chiavi e rappresentazioni delle chiavi

Gli standard JOSE, che coprono JWS, JWT firmati e criptati e altro ancora, descrivono come utilizzare le chiavi di crittografia per firmare o criptare le informazioni. Gli elementi fondamentali di qualsiasi operazione di crittografia includono l'algoritmo e la chiave. Diversi algoritmi richiedono tipi di chiavi e, in alcuni casi, dimensioni diverse.

Gli algoritmi simmetrici, come la famiglia HS* per la firma o l'algoritmo A128KW per la crittografia, richiedono chiavi simmetriche o condivise: la stessa chiave viene utilizzata per la firma e la verifica o per la crittografia e la decrittografia. Gli algoritmi asimmetrici, come gli algoritmi RS*, PS* ed ES* per la firma o gli algoritmi ECDH* per la crittografia, utilizzano coppie di chiavi: una chiave pubblica e una chiave privata, che sono abbinate. Durante la firma, il firmatario utilizza la chiave privata per firmare e qualsiasi interessato può utilizzare la chiave pubblica per verificare la firma. Durante la crittografia, l'operatore di crittografia utilizza la chiave pubblica per criptare e l'operatore di decrittografia utilizza la chiave privata per decriptare. Le chiavi pubbliche, come suggerisce il nome, sono condivisibili pubblicamente e non devono essere tenute segrete.

Esistono diversi modi per serializzare le chiavi di crittografia in formato di testo. I criteri Apigee accettano chiavi serializzate in vari formati: formato con codifica PEM, formato JWKS o, per le chiavi condivise, formato con codifica UTF-8 o base64.

Formato PEM

Per le chiavi pubbliche o private, è comune utilizzare la codifica PEM, definita in IETF RFC 7468. Ecco un esempio di chiave privata rappresentata in formato PEM:

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

Esistono formati PEM simili per le chiavi pubbliche o le chiavi private criptate.

Formato JWKS

Una chiave web JSON (JWK) è una struttura di dati JSON che rappresenta una singola chiave crittografica. Un insieme di chiavi web JSON (JWKS) è una struttura JSON che rappresenta un insieme di JWK. JWK e JWKS sono descritti nella RFC7517. Consulta gli esempi di JWKS nell'Appendice A. Esempi di set di chiavi web JSON.

JWKS è progettato per consentire a qualsiasi entità di rappresentare un insieme di chiavi in un formato standard. Un caso d'uso chiave è la condivisione delle chiavi pubbliche in modo standard, tramite un endpoint HTTP che fornisce i dati in formato JWKS. Quando un'azienda o un sistema che genera JWS o JWT firmati, ad esempio un fornitore di servizi di identità, pubblica le proprie chiavi pubbliche, qualsiasi sistema o applicazione in grado di leggerle può verificare le firme generate dalla parte che esegue la firma. Al contrario, qualsiasi sistema o app che voglia criptare i dati che devono essere letti solo da una determinata azienda o entità, può recuperare le chiavi pubbliche appartenenti a quella azienda o entità e generare un JWT criptato a questo scopo.

La RFC7517 descrive gli elementi chiave JWKS per ogni tipo di chiave, ad esempio RSA o EC. Questi elementi devono essere sempre presenti:

  • kty: il tipo di chiave, ad esempio RSA o EC.
  • kid: l'ID chiave. Può essere un valore di stringa univoco arbitrario; non devono essere presenti duplicati all'interno di un singolo insieme di chiavi. Se il JWT in entrata contiene un ID chiave presente nell'insieme di JWKS, il criterio VerifyJWS o VerifyJWT utilizzerà la chiave pubblica corretta per verificare la firma JWS/JWT.

Di seguito sono riportati esempi di elementi facoltativi e dei relativi valori:

  • alg: l'algoritmo della chiave. Deve corrispondere all'algoritmo di firma in JWS/JWT.
  • use: l'utilizzo previsto della chiave. I valori tipici sono "sig" per la firma e la verifica o "enc" per la crittografia e la decrittografia.

Il seguente JWKS (recuperato originariamente da https://www.googleapis.com/oauth2/v3/certs, ma ora non più aggiornato) include gli elementi e i valori richiesti e può essere utilizzato da 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",
        }
     ]
  }
  

Specifica delle chiavi per i criteri JWS e JWT

Indipendentemente dal fatto che tu stia generando o verificando JWS o JWT, devi fornire una chiave da utilizzare all'interno delle operazioni di crittografia.

Quando generi un JWT firmato, devi fornire una chiave che possa produrre la firma.

  • Nel caso di un algoritmo di firma RS*, PS* o ES*, che utilizzano tutti chiavi asimmetriche, devi fornire la chiave privata per generare la firma.
  • Nel caso di un algoritmo HS*, devi fornire la chiave simmetrica che verrà utilizzata durante la generazione della firma.

Quando verifichi un JWS/JWT firmato, devi fornire una chiave che possa verificare la firma.

  • Nel caso di un algoritmo di firma RS*, PS* o ES*, devi fornire la chiave pubblica associata alla chiave privata utilizzata originariamente per firmare il token.
  • Nel caso di un algoritmo HS*, devi fornire la stessa chiave simmetrica utilizzata per firmare il JWS o il JWT.

Hai due opzioni per fornire le chiavi ai criteri JWS e JWT:

  • Fornire direttamente il valore della chiave (in genere tramite una variabile di contesto) oppure
  • Fornisci la chiave indirettamente tramite un kid e un JWKS. Puoi specificare il JWKS direttamente o indirettamente tramite un URL http da cui Apigee può recuperare il JWKS.

L'opzione URL JWKS viene in genere utilizzata solo come origine di chiavi pubbliche utilizzabili con algoritmi asimmetrici, in quanto gli URL JWKS sono in genere pubblici.

Gli esempi seguenti illustrano i modi in cui puoi fornire le chiavi direttamente in vari scenari.

  • Genera un JWT firmato con l'algoritmo HS256. La chiave obbligatoria in questo caso è una chiave simmetrica. Questo criterio fornisce una variabile di contesto che contiene la chiave segreta con codifica 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>
  • Verifica un JWT firmato con l'algoritmo HS256. In questo caso, la chiave richiesta è una chiave simmetrica. Come nell'esempio precedente, questo criterio fornisce una variabile di contesto che contiene la chiave segreta codificata in 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>
  • Verifica un JWT che è stato firmato con l'algoritmo PS256. In questo caso, la chiave richiesta è una chiave pubblica RSA. Questo criterio fornisce una variabile di contesto contenente la chiave pubblica codificata in PEM.

    <VerifyJWT name='JWT-001'>
      <Algorithm>PS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
        <Value ref='variable-containing-pem-encoded-public-key'/>
      </PublicKey>
      . . .
    </VerifyJWT>
  • Genera un JWT firmato con l'algoritmo PS256. In questo caso, la chiave richiesta è una chiave RSA privata. Questo criterio fornisce una variabile di contesto che contiene la chiave privata con codifica PEM.

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

JWKS come origine delle chiavi durante la verifica di un JWS o di un JWT firmato

Quando un sistema o un'app genera un JWS/JWT, in genere inserisce un identificatore chiave (la rivendicazione kid) nell'intestazione JWS/JWT. La chiave indica a qualsiasi lettore del JWS/JWT quale chiave è necessaria per verificare la firma sul JWS/JWT firmato o decriptare il JWT criptato.

Ad esempio, supponiamo che un emittente firmi un JWT con una chiave privata. L'"ID chiave" identifica la chiave pubblica corrispondente che deve essere utilizzata per verificare il JWT. L'elenco delle chiavi pubbliche è in genere disponibile su un endpoint noto, ad esempio l'endpoint Google Identity o l'endpoint Firebase Authentication. Altri provider avranno i propri endpoint pubblici che pubblicano le chiavi in formato JWKS.

Quando utilizzi Apigee per verificare un JWS o un JWT firmato con chiavi pubbliche condivise tramite un endpoint JWKS, hai alcune opzioni:

  • Opzione 1: nella configurazione dei criteri, specifica l'URI dell'endpoint JWKS nell'elemento <PublicKey/JWKS>. Ad esempio, per il criterio 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>

    In questo caso, Apigee:

    1. Esamina l'intestazione JWS/JWT per trovare l'algoritmo di firma (alg), ad esempio RS256, e rifiuta il JWT in entrata se l'algoritmo non corrisponde a quello configurato nel criterio.
    2. Recupera l'elenco delle chiavi con i relativi ID dall'endpoint JWKS specificato o da una cache interna se questo endpoint JWKS è stato utilizzato in precedenza.
    3. Esamina l'intestazione JWS/JWT per trovare l'ID chiave (kid). Se il JWT in entrata non include un ID chiave (kid) nell'intestazione, la mappatura di kid a verification-key non è possibile e Apigee genera un errore.
    4. Estrai dal JWKS il JWK con l'ID chiave indicato nell'intestazione JWS/JWT. Genera un errore se non è presente una chiave con quell'ID chiave.
    5. Verifica che l'algoritmo per il JWK corrisponda a quello specificato nella configurazione del criterio. Rifiutare la verifica e generare un errore se gli algoritmi non corrispondono.
    6. Utilizza questa chiave pubblica per verificare la firma su JWS/JWT. Rifiutare la verifica e generare un errore se la firma non viene verificata.
  • Opzione 2: nella configurazione del criterio, specifica una variabile che contenga l'URI dell'endpoint JWKS nell'elemento <PublicKey/JWKS>.

    Ad esempio, per il criterio 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>

    In questo caso, Apigee eseguirà gli stessi passaggi descritti sopra, tranne per il fatto che recupererà il JWKS non da un URI hardcoded, ma dall'URI specificato nella variabile a cui fa riferimento l'attributo uriRef. La memorizzazione nella cache rimane valida.

  • Opzione 3: nella configurazione del criterio, specifica una variabile che contenga i dati JWKS hardcoded nell'elemento <PublicKey/JWKS>.

    Ad esempio, per il criterio 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>

    In questo caso, Apigee eseguirà gli stessi passaggi descritti sopra, tranne per il fatto che recupererà i JWK non da un URI, ma dalla variabile di contesto specificata nell'attributo ref. In genere, questa variabile di contesto viene caricata da un ServiceCallout, da un KVM o da un file delle proprietà associato al proxy.

JWKS come origine della chiave durante la generazione di un JWT criptato

Quando generi un JWT criptato tramite un algoritmo asimmetrico (RSA-OAEP-256 o una delle varianti ECDH-*), utilizzi la chiave pubblica per la crittografia. Hai a disposizione opzioni per fornire la chiave al criterio GenerateJWT

Un approccio tipico è specificare nella configurazione del criterio l'URI dell'endpoint JWKS nell'elemento <PublicKey/JWKS>. Ad esempio:

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

In questo caso, Apigee:

  1. Assembla il payload e l'intestazione non codificati per il JWT in base alla configurazione del criterio.
  2. Recupera l'elenco delle chiavi con i relativi ID dall'endpoint JWKS specificato o da una cache interna se questo endpoint JWKS è stato utilizzato in precedenza. Attualmente il TTL della cache è di 5 minuti.
  3. Estrai il JWK con l'ID chiave indicato nell'elemento PublicKey/Id dal JWKS. Genera un errore se non è presente una chiave con quell'ID chiave.
  4. Verifica che l'algoritmo per il JWK corrisponda a quello specificato nella configurazione del criterio. Genera un errore se gli algoritmi non corrispondono.
  5. Genera una sequenza casuale da utilizzare come chiave di crittografia dei contenuti.
  6. Utilizza la chiave pubblica selezionata per criptare la chiave di crittografia dei contenuti.
  7. Utilizza la chiave di crittografia dei contenuti per criptare il payload.
  8. Infine, assembla tutti i componenti in un JWT criptato serializzato.

Un'alternativa è utilizzare l'attributo uriRef per specificare una variabile che contenga l'URI di un endpoint JWKS. Ad esempio:

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

In questo caso, Apigee eseguirà gli stessi passaggi descritti sopra, tranne per il fatto che recupererà i JWK dall'URI specificato nella variabile a cui fa riferimento l'attributo uriRef, anziché da un URI hardcoded. Apigee leggerà il JWKS da una cache interna se questo endpoint JWKS è stato utilizzato in precedenza.