Hello ,
Below is the policy snippet for verify JWT :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VerifyJWT async="false" continueOnError="false" enabled="true" name="verifyJWT">
<Algorithm>RS256</Algorithm>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<PublicKey>
<JWKS uri=" Cert url"/>
</PublicKey>
<AdditionalHeaders/>
<IgnoreCriticalHeaders>false</IgnoreCriticalHeaders>
<AdditionalClaims/>
<IgnoreIssuedAt>false</IgnoreIssuedAt>
</VerifyJWT>
and the content of uri is given below
{"keys":[{"kty":"RSA","use":"sig","kid":"2","x5c”:[“*********\u003d\u003d"]},,{"kty":"RSA","use":"sig","kid":"1","x5c”:[“*****************************”]}]}
When a JWT Token is sentfor verification, below error is displayed .
jwt.verifyJWT.error
Could not find a matching Public Key: policy(verifyJWT) |
{"fault":{"faultstring":"Could not find a matching Public Key: policy(verifyJWT)","detail":{"errorcode":"steps.jwt.NoMatchingPublicKey"}}}
Solved! Go to Solution.
You can try using this Java callout to transform your JWKS:
Hi @dchiesa1 ,
Thanks for the API Bundle. We will try from our end will update the status
Regards,
Suma
What kid
is present in the JWT header?
Apigee will select a JWK from the JWKS, based on the kid
field in the JWT header. ( kid
stands for Key ID). Your JWKS has two JWK, one with kid="1" and another with kid="2". If your JWT has a field like "kid" : "1"
or "kid" : "2"
, then Apigee will find the appropriate JWK. If your JWT does not have a kid
field in the header or the value of the kid
field in the header does not match one of the kids in the JWKS, then you will see the error "Could not find a matching Public Key". This is as expected and desired. We do not want to verify JWT that have been signed with unknown keys.
To understand what kid is in the header, you can paste your JWT into an online decoder, like this one. Results will be like so:
As you can see in this case the kid field in the decoded header holds "abcdefg".
Hello,
Thanks for the response.
In the Trace files, we can see that the header value is Kid 2 (as attached in the snapshot) , and it is still not able to refer the certificate of kid 2 and throws error given below
Could not find a matching Public Key
Also we tried sending only 1st array value from the Url into a flow variable and sending the variable in the public key . This also throws the same error .please refer below :
in the abobe policy there is base64 encoded value for ==. We have tried sending both \u003d and == in the value but same error .
Request you to help us solve the issue .
Thanks,
Suma
So it is not a problem with the kid value.
Ah, I think I see the problem. I Think the Apigee policy will select a key only if the entry has an n and e property. the Apigee policy will not resolve a key if the key is specified as x5c or x5u. This is a limitation of the Apigee policy. If you can get your JWKS into a form that publishes n and e , rather than , or in addition to x5c, then the key selection should work the way you want it to.
{"keys":
[{
"kty":"RSA",
"kid":"no-good--will-not-be-selected-by-Apigee",
"x5c":
["MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSIb3D...vdXK3IVfOWA=="]
},
{
"kty":"RSA",
"kid":"good-this-will-work",
"n": "0vx7agoebGcQSuuPi...JzKnqDKgw",
"e":"AQAB"
}
]
}
Thanks for the details. We noticed that n and e were missing from the certificate endpoint but we were not sure if they are mandatory attributes to be included in Apigee policy. We will check with our internal team exposing these details .
Good observation @dchiesa1 .
@suma : Can you check the JSON structure that is returned as part of the JWKS endpoint call? Do not construct the JSON structure at your own will, as this will never work. You need to understand each attribute before attempting to do so.
For good reference go thru the spec and understand the what JWKS https://datatracker.ietf.org/doc/html/rfc7517
Apigee document reference:
Hello,
Yes we did check and we were not sure of n and e to be present as part of policy. We'll check internally for these attributes .
Thanks
Suma
It is pretty straightforward to derive an n and e parameter from an x5c. So if absolutely necessary, you could ... insert an Apigee proxy in front of your JWKS endpoint, and do that transformation dynamically. Then specify the jwks-proxy URL, rather than the actual JWKS endpoint, in your VerifyJWT policy.
The jwks-proxy should, in the response flow,
This would best be done in a Java callout.
But the ideal approach would be for the JWKS endpoint to just publish {n,e} directly.
You can try using this Java callout to transform your JWKS:
Hi @dchiesa1 ,
Thanks for the API Bundle. We will try from our end will update the status
Regards,
Suma