Announcements
This site is in read only until July 22 as we migrate to a new platform; refer to this community post for more details.
Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

JWT validation Failed with Invalid Key configuration error

Hi All,

 

I am facing below issue in verifying the JWT in APIGEE. I am using below code in Verify JWT policy 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VerifyJWT async="false" continueOnError="false" enabled="true" name="Verify-JWT-1">
<DisplayName>Verify JWT-1</DisplayName>
<Algorithm>RS256</Algorithm>
<PublicKey>
<JWKS ref="jwksResponse.content"/>
</PublicKey>
</VerifyJWT>

 

Before that i am getting the JWKS values using Service Callout policy

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="SC-Get-JWT-Public-Key">
<DisplayName>SC Get JWT Public Key</DisplayName>
<Request clearPayload="false" variable="jwksRequest">
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</Request>
<Response>jwksResponse</Response>
<HTTPTargetConnection>
<Properties/>
<URL>https://accounts.eu1.gigya.com/accounts.getJWTPublicKey</URL>
</HTTPTargetConnection>
</ServiceCallout>

 

error i am getting as like below 

 

{"fault":{"faultstring":"Invalid Key configuration : policy(Verify-JWT-1) element(PublicKey)","detail":{"errorcode":"steps.jwt.InvalidKeyConfiguration"}}}

 

I tried many ways but i am not able to find the solution. Could anyone help on this please.

 

Thanks in advance

Vignesh 

 

I followed @dchiesa1 video to create JWT flow for validation   

Solved Solved
0 13 4,298
1 ACCEPTED SOLUTION

Yes, I'm sorry, there's a mismatch between what Apigee is expecting, and what Gigya is sending. 

Apigee is expecting a JWKS, a JWK Set.  A Set of JWK things.  Each JWK looks like: 

{ 
 "kty": "RSA",
 "n": "qoQah4...",
 "e": "AQAB",
 "alg": "RS256",
 "use": "sig",
 "kid": "REQ0M...",
  ...other fields possible here...
}

And a JWKS is just a set of those.  It looks like this: 

{
  "keys": [
    {"kty":"RSA","n":"...", "e" : "..." ... }, 
    {"kty":"RSA","n":"...", "e" : "..." ... }, 
    {"kty":"RSA","n":"...", "e" : "..." ... }, 
      ...
   ]
}

In other words, Apigee is expecting a JSON that contains a single member "keys", which has an array of JWK.  Your endpoint is sending a single JWK.  That's the reason for the problem .  The key that Gigya is sending is valid and good, but Apigee isn't smart enough to figure out that it's exactly one key.  Apigee is looking for a JWKS. 

How to fix this? 

The way I might do it: use ServiceCallout to the Gigya URL to obtain the JWK.  Then use a Javascript policy to build a JWKS from that.  It would look like this: 

// In the line below, replace serviceCalloutResponse with the name of the 
// response variable you used in your ServiceCallout policy.  
var r = JSON.parse(context.getVariable('serviceCalloutResponse.content'));
var jwks = { keys : [ r ] } ; 
context.setVariable('myjwks', JSON.stringify(jwks));

Then, specify in your VerifyJWT policy: 

<VerifyJWT name="Verify-JWT-1">
  <Algorithm>RS256</Algorithm>
  <PublicKey>
    <JWKS ref="myjwks"/>
  </PublicKey>
</VerifyJWT>

This will "work" , but if you implement it naively, then ServiceCallout will invoke the public key endpoint EVERY TIME you verify a JWT.  Which is unnecessary.  So to be smarter, you will need to insert the response into a cache.  Use PopulateCache and LookupCache for that purpose.

 

The other alternative is to somehow persuade Gigya to return a JWKS directly, instead of a single JWK.  I don't know Gigya and I don't know if that is possible.  The VerifyJWT policy will automatically cache the JWKS when you specify the JWKS URL directly. 

 

 

View solution in original post

13 REPLIES 13