i am preparing a new training lab (WSO2) where the...
# help
r
i am preparing a new training lab (WSO2) where the X-JWT-Assertion Header needs to be decoded and basically the Json payload needs to be in the body. Originally i have a backend service but that requires another instance. I saw that i could get the header into the response { \"copiedHeader\": \"{{request.headers.X-JWT-Assertion}}\" } however, decoding the payload using : { "message": "Extracted user from custom JWT assertion header", "userId": "{{#assign 'jwtPayload'}}{{base64 (regexExtract request.headers.X-JWT-Assertion '([^.]+)\\.([^.]+)\\.([^.]+)' group=2) decode=true}}{{/assign}}{{#assign 'claims'}}{{parseJson jwtPayload}}{{/assign}}{{claims.sub}}" } give 500 [ERROR] 126 java.lang.IllegalArgumentException: Illegal base64 character 5b when i do this { "status": "success", "userId": "{{#assign 'jwtSegments'}}{{split request.headers.[X-JWT-Assertion] '.'}}{{/assign}}{{#assign 'payloadSegment'}}{{jwtSegments.[1]}}{{/assign}}{{#assign 'jwtPayload'}}{{base64 payloadSegment decode=true}}{{/assign}}{{#assign 'claims'}}{{parseJson jwtPayload}}{{/assign}}{{claims.sub}}", "apiName": "{{#assign 'jwtSegments'}}{{split request.headers.[X-JWT-Assertion] '.'}}{{/assign}}{{#assign 'payloadSegment'}}{{jwtSegments.[1]}}{{/assign}}{{#assign 'jwtPayload'}}{{base64 payloadSegment decode=true}}{{/assign}}{{#assign 'claims'}}{{parseJson jwtPayload}}{{/assign}}{{formData claims 'wso2.org/claims/apiname'}}" } there is no error but an empty payload "status": "success", "userId": "", "apiName": "" } what are the right steps to decode this JWT X-JWT-Assertion eyJ4NXQiOiJOR1k1T1dVNU5EVTNaakl6TjJVM1kyVTNNV1JqT0RkbFlUUXhaRE16TVRZMVpEbGxZemN4TWc9PSIsImtpZCI6IlEwNDliRzlqWVd4b2IzTjBMQ0JQVlQxWFUwOHlMQ0JQUFZkVFR6SXNJRXc5VFc5MWJuUmhhVzRnVm1sbGR5d2dVMVE5UTBFc0lFTTlWVk1qTlRrd056WTFOVGN3TmpJMU1qQTBNVGN3T1RBM05qTXpNVEU1T0RnNE5qVXhOVGM0T0RFeU5URTFNekF5TVRNeSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI4OWQ3MTVjNi0wZDNlLTQyOWYtYjIwYy1lOWJmYmM2ZmI3NjgiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcGluYW1lIjoiUGl6emFTaGFja0FQSSIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2FwcGxpY2F0aW9udGllciI6IlVubGltaXRlZCIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL3ZlcnNpb24iOiIxLjAuMCIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2tleXR5cGUiOiJTQU5EQk9YIiwiaXNzIjoid3NvMi5vcmdcL3Byb2R1Y3RzXC9hbSIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2FwcGxpY2F0aW9ubmFtZSI6IkRlZmF1bHRBcHBsaWNhdGlvbiIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2VuZHVzZXIiOiJhZG1pbkBjYXJib24uc3VwZXIiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9lbmR1c2VyVGVuYW50SWQiOiItMTIzNCIsInV1aWQiOiI5OTUyYjM2Ny05MmRjLTQzMWMtODRlNy02MGZhZWZlZWZkMGIiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcHBsaWNhdGlvblVVSWQiOiI5MzIwZjRhZS03MzgxLTRiOTEtOTEzZi0yYjkxN2RhZGYxOWIiLCJjbGllbnRfaWQiOiJkMWdtSm1JQTRTS3JZa3hkYjNOTTRpaXQ0Q29hIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvc3Vic2NyaWJlciI6ImFkbWluIiwiYXpwIjoiZDFnbUptSUE0U0tyWWt4ZGIzTk00aWl0NENvYSIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL3RpZXIiOiJVbmxpbWl0ZWQiLCJzY29wZSI6ImRlZmF1bHQiLCJleHAiOjE3ODc2NjA1NjIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL2FwcGxpY2F0aW9uaWQiOiIxIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvdXNlcnR5cGUiOiJBcHBsaWNhdGlvbl9Vc2VyIiwiaWF0IjoxNzg3NjU5NjYyLCJqdGkiOiIxNDQ2M2MzNy04ZDQ5LTRhNTQtODQ0ZC0xODJhNTVmZGY2YWYiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcGljb250ZXh0IjoiXC9waXp6YXNoYWNrXC8xLjAuMCJ9.azO/wET5wRF+zR/V9exHTMCDxxJRD5llqz15Hlj7V6t9/TfJJ1lgx4fADbkj2oO2qES02Je3JHIPOya7fkdl3mhdYpXdCSO6PgNNbrJwJ8Y5SIKeTtZ0h/82d2OVgiKE7kOK73QOBCkzth6/jpqEwUMyiBgVWAXLFmxdlO7qEq1f2LS25HEICodAVYfBEQQ/XfKeEpREN1f0vqOKynJZUaLo0z8Oq1jQ8UpmZSAYh6eJhjHtZQzlXj6EIEZVXhUXmTNAmNTpksar4rZcOLkMF+zfOA3RHhsktSdcXsPVbRt7M8K0dUXVWGT9NJ+oHzDktLtDxD6j/js+4X0NddEbRg
t
Hi @rob.blaauboer, I can’t get your example JWT to parse in jwt.io. Seems the signature is encrypted maybe? This might also be confusing the WM parser.
r
hi @Tom if you go to wso2-cs.github.io/cs-tools and use the JWT decoder you can decode it. it is a bit tricky
I have a backend that decodes it (but i fdo not want another backend up and running for labs if we are able to do it in Wiremock. <variable name="jwt" type="STRING" expression="${headers['X-JWT-Assertion']}"/> <variable name="jwtParts" type="JSON" expression="${split(vars.jwt, '[.]')}"/> <variable name="claims" type="JSON" expression="${object(base64decode(replace(replace(vars.jwtParts[1], '-', '+'), '_', '/')))}"/> <payloadFactory media-type="json" template-type="default"> <format>${vars.claims}</format> </payloadFactory> <variable name="apiname" type="STRING" expression="${payload.['wso2.org/claims/apiname']}"/> <log category="INFO" logMessageID="false" logFullPayload="false"> <message>${vars.claims.uuid}${vars.apiname}</message> </log> <respond/>
image.png
t
This seems to work:
Copy code
{{#trim}}
{{val request.headers.[X-JWT-Assertion].[0] assign='jwtString'}}
{{val (split jwtString '.') assign='jwtSegments'}}
{{val (lookup (split jwtString '.') '[1]') assign='payloadSegment'}}
{{val (base64 payloadSegment decode=true) assign='jwtPayload'}}
{{val (parseJson jwtPayload) assign='jwtClaims'}}
{{#formatJson}}
{
  "status": "success",
  "userId":  "{{jwtClaims.sub}}",
  "apiName": "{{lookup jwtClaims '[<http://wso2.org/claims/apiname]'}}>"
}
{{/formatJson}}
{{/trim}}
r
great @Tom thanks. I am impressed by the functionality of the product. I am moving more and more of my training backends to wiremock. We can take a look to see if i can incorporate more
t
That's great to hear, thanks for the kind feedback! And please don't hesitate to shout if we can help with anything else.
Documented this approach for anyone else that wants to do this in future: docs.wiremock.io/response-templating/using-jwt-claims-from-request