Getting Consumer Secret for JWT - jwtDecode.js not working

Not applicable

I am trying to implement the following flow for API authentication. To be clear I am not using Oauth 2.0 tokens. These are customized JWT with information in the payload.

1. Proxy Endpoint receives a JWT

2. Proxy looks at the header of the JWT and from the "ISS" field extracts the information which is the consumer key

3. Use "Verify API Key" to get the consumer secret from the consumer key.

4. Validate the JWT using the consumer secret/secret key (using JWT-Parse-HS256).

To accomplish this flow I have tried using Dino's Java callouts for step 2. However this callout while extracting the needed information throws up a 500 internal server error because it does not have a valid secret key. I can not find anyway to get the callout to work without a valid secret key.

So my next strategy was to try and parse out the header string of the JWT and then base64 decode it to get the iss string I need. I don't think I can use the Basic Authentication library for this. What is the best way to base64 decode a string in Apigee? I tried using the jwtDecode.js function but I am struggling to get it to work.

Any tips would be most appreciated.

Solved Solved
1 5 464
1 ACCEPTED SOLUTION

Yep, ok.... I understand. I have done similarly.

I used a simple JS callout to do a string split (on the dots) and then a base64 decode, to get the JWT payload, then extract the iss value to get the consumerkey. You said you had trouble with the jwtDecode.js thing... that's the code I've used successfully. Maybe we should try to figure out what's going wrong with THAT.

Addendum @Keith Kowal - I have updated the Java callout that Parses JWT, to now include a wantVerify property. This is in version 1.0.9 of the jar. The wantVerify property defaults to true. If you set it to false, then the JWT will be parsed but not verified. This should set the jwt_issuer for you, which would allow you to do what you want.

Using wantVerify=false would eliminate the need to use a JS callout to split and parse the JWT. Instead of the sequence of { JS callout, VerifyApiKey Java callout to verify the JWT}, you would use { Java (JWT) callout to parse the JWT (with wantVerify = false), VerifyApiKey, JWT callout with wantVerify=true} . This is how to set the property to false.

  <JavaCallout name='JWT-Parse'>
    <Properties>
      <Property name="wantVerify">false</Property>
      <Property name="algorithm">HS256</Property>
      <Property name="jwt">{request.formparam.jwt}</Property>
    </Properties>
    <ClassName>com.apigee.callout.jwtsigned.JwtParserCallout</ClassName>
    <ResourceURL>java://apigee-edge-callout-jwt-signed-1.0.9.jar</ResourceURL>
  </JavaCallout>

You will not need to specify the secret-key when wantVerify=false.

View solution in original post

5 REPLIES 5

Former Community Member
Not applicable

HS256 algorithm requires a secret (to validate the signature of the JWS). You will need a valid secret to verify the JWT.

Please see below the question I asked:

So my next strategy was to try and parse out the header string of the JWT and then base64 decode it to get the iss string I need. I don't think I can use the Basic Authentication library for this. What is the best way to base64 decode a string in Apigee? I tried using the jwtDecode.js function but I am struggling to get it to work.

Yep, ok.... I understand. I have done similarly.

I used a simple JS callout to do a string split (on the dots) and then a base64 decode, to get the JWT payload, then extract the iss value to get the consumerkey. You said you had trouble with the jwtDecode.js thing... that's the code I've used successfully. Maybe we should try to figure out what's going wrong with THAT.

Addendum @Keith Kowal - I have updated the Java callout that Parses JWT, to now include a wantVerify property. This is in version 1.0.9 of the jar. The wantVerify property defaults to true. If you set it to false, then the JWT will be parsed but not verified. This should set the jwt_issuer for you, which would allow you to do what you want.

Using wantVerify=false would eliminate the need to use a JS callout to split and parse the JWT. Instead of the sequence of { JS callout, VerifyApiKey Java callout to verify the JWT}, you would use { Java (JWT) callout to parse the JWT (with wantVerify = false), VerifyApiKey, JWT callout with wantVerify=true} . This is how to set the property to false.

  <JavaCallout name='JWT-Parse'>
    <Properties>
      <Property name="wantVerify">false</Property>
      <Property name="algorithm">HS256</Property>
      <Property name="jwt">{request.formparam.jwt}</Property>
    </Properties>
    <ClassName>com.apigee.callout.jwtsigned.JwtParserCallout</ClassName>
    <ResourceURL>java://apigee-edge-callout-jwt-signed-1.0.9.jar</ResourceURL>
  </JavaCallout>

You will not need to specify the secret-key when wantVerify=false.

@Dino

That did the trick. Your the man Dino.

Many thanks.

Glad to help, Keith! Your question prompted an improvement in the callout, so it's win/win!