When verifying an auth token using the JWKS uri as the public key, I receive a 500 internal error:
{
"fault": {
"faultstring": "NullPointerException",
"detail": {
"errorcode": "Internal Server Error"
}
}
}
The auth token is coming in via the authorization header.
My VerifyJWS policy looks like:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VerifyJWS name="JWS-VerifyIdaToken" enabled="true">
<DisplayName>JWS-VerifyIdaToken</DisplayName>
<Algorithm>RS256</Algorithm>
<PublicKey>
<JWKS uri="https:/jwks_uri/jwks"/>
</PublicKey>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</VerifyJWS>
My trace output for the VerifyJWS policy step clearly show itâs able to pull the required properties from the looks like:
Variables Read and Assigned
|
|
jws.JWS-VerifyIdaToken.valid
|
false
|
|
jws.JWS-VerifyIdaToken.header-json
|
|
|
jws.JWS-VerifyIdaToken.header-claim-names
|
[x5t, kid, typ, alg]
|
|
jws.JWS-VerifyIdaToken.decoded.header.x5t
|
BrfGYpn6HU1Uc6PwDue94PM3rgA
|
|
jws.JWS-VerifyIdaToken.decoded.header.kid
|
gou8yAJLiQVa0eoEjcl4Y2aXlsgQrKsOnyiNILUgZiQ
|
|
jws.JWS-VerifyIdaToken.decoded.header.typ
|
|
jws.JWS-VerifyIdaToken.decoded.header.alg
|
RS256
|
|
JWS.failed
|
true
|
|
|
|
|
Content-Type
|
application/json
|
|
Error Content â Body
|
{âfaultâ:{âfaultstringâ:âNullPointerExceptionâ,âdetailâ:{âerrorcodeâ:âInternal Server Errorâ}}}
|
|
action
|
ABORT
|
|
stepDefinition-async
|
false
|
|
internal
|
false
|
|
stepDefinition-type
|
JWS
|
|
type
|
VerifyJWSStepExecution
|
|
enforcement
|
request
|
|
stepDefinition-continueOnError
|
false
|
|
stepDefinition-displayName
|
JWS-VerifyIdaToken
|
|
stepDefinition-name
|
JWS-VerifyIdaToken
|
|
stepDefinition-enabled
|
true
|
|
result
|
false
|
|
error
|
null
|
|
type
|
ErrorPoint
|
|
state
|
PROXY_REQ_FLOW
|
|
error.class
|
java.lang.NullPointerException
|
|
Identifier
|
fault
|
Iâve been able to verify the token using other online services such as https://jwt.davetonge.co.uk/
2 Likes
This is possibly a bug with where it is unable to retrieve the JWKS if passed as a URI.
Please confirm that if you pass in the JWKS as a ref (use a ServiceCallout policy to grab the JWKS before the ValidateJWS) works?
1 Like
Hi Joey,
Yes, using a service callout to fetch the jwks payload works fine.
For posterity..
My ServiceCallout policy:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="SC-FetchJwks">
<DisplayName>SC-FetchJwks</DisplayName>
<Properties/>
<Request clearPayload="true" variable="jwksRequest">
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</Request>
<Response>jwksResponse</Response>
<HTTPTargetConnection>
<Properties/>
<URL>http://jwks_uri/jwks</URL>
</HTTPTargetConnection>
</ServiceCallout>
My VerifyJWS policy:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VerifyJWS name="JWS-VerifyToken">
<DisplayName>JWS-VerifyToken</DisplayName>
<Algorithm>RS256</Algorithm>
<PublicKey>
<JWKS ref="jwksResponse.content"/>
</PublicKey>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<KnownHeaders/>
<IgnoreCriticalHeaders/>
</VerifyJWS>
1 Like
Thanks for the example code.
The relevant bug is b/139360107.
Just a further suggestion: itâs probably a good idea to cache the result of the SC-FetchJwks for maybe 30 minutes or so. Rather than invoking the ServiceCallout for every time you verify a token, youâd use the same JWKS data, from cache. That means the sequence would not be:
- ServiceCallout - to fetch JWKS
- VerifyJWT (specifying the jwksResponse.content for the JWKS data)
But instead it would be:
- LookupCache - to see if JWKS response is present
- ServiceCallout - conditional, to retrieve jwksResponse if cache is cold
- PopulateCache - conditional, to set the cache
- LookupCache - conditional, to retrieve the just cached data into a context variable
- VerifyJWT
2 Likes
Thanks Dino. Iâll add to that ticket.
The bug seems to have been resolved. However, if I try to use a variable in the address,
<JWKS uri="https://{oam_env}/connect/jwk_uri"/>
to dynamically change the destination based on the Apigee deployment environment, still it returns a 500 error
{
"fault": {
"faultstring": "NullPointerException",
"detail": {
"errorcode": "Internal Server Error"
}
}
}
Am I doing something wrong or is it not allowed to use the variables in this case?
Thanks for your help.
The bug seems to have been resolved.
Glad to hear it.
Am I doing something wrong
Yes
or is it not allowed to use the variables in this case?
yes, it is not allowed.
There is a SEPARATE feature enhancement which will allow you to specify a variable that holds the URI. It wonât be a message template, but it will be a variable, like (uriref=âvariablenameâ). ref: b/139642475. I donât have an estimate on availability of that feature. For now you need to use hard-coded URIs.
And also, getting a fault that says âNullPointerExceptionâ seems to also be a bug in Apigee. It shouldnât do that. It should instead just fail to resolve the host. I think maybe you will still get a 500 error, but, it shouldnât give you a lame message like âNullPointerExceptionâ . Thanks for reporting that. r/159341213