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! Go to 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.