Passing Enduser Attributes to the Backend Using JWE (JSON Web Encryption) WSO2 API Manager 3.2.0

Shanaka Sandanayaka
4 min readJan 29, 2021

--

I have discussed with my previous blog, We can use JWT tokens instead of the classic session-based tokens as well as to pass data between multiple parties over the network.

In JWT, User data claims are passed to the backend just with an encoding. If someone gets the JWT token, It’s very easy to decode and see the content inside the token. To avoid such cases and put an additional layer of security if the claims contain very sensitive data, JWE (JSON Web Encryption) is introduced.

WSO2 API Manager the Leader of the open-source API Management solutions, There is an option to pass the end-users attributes to the backend with the JWT token. Since we can easily customize the WSO2 products, If there is a requirement to use JWE to pass those attributes, We can achieve it with a simple custom JWT generator.

Custom JWE Generator

In order to implement the JWE token i have used the nimbus java library. But there are so many different java libraries to achieve this.

Unlike the JWT, JWE uses public-key encryption to encrypt the token. But in JWT use a private key to sign the token. But in JWE use a public key from a key pair to encrypt the token and from the backend, It is required to have a private key to decrypt the content of the JWE.

Please clone the following repo to get the implementation of the JWE.

In this case, I have extended the APIMgtGatewayJWTGeneratorImpl, This class is used to generate the usual backend JWT token. The aforementioned class dose contains all required methods to collect all the relevant standard and custom claims. In our customized class i have override the generateToken method only.

And also, I have used WSO2's default public certificates key to encrypt the JWT token.

  • Then we use maven build command to build the project.
mvn clean install
  • Once the build complete, Copy the jar file to the <AM_HOME>/repository/components/dropins folder.
  • Then enable the backend JWT from the deployment.toml file as well as change the impl class.
  • Once all done, Restart the server.

If everything setup correctly, Once you invoke an API, The JWT token should be passed to the backend as a header with the name X-JWT-Assertion. If the wire logs enabled, Then we can check the JWE token.

[2021-01-29 23:25:46,086]  INFO - TimeoutHandler This engine will expire all callbacks after GLOBAL_TIMEOUT: 120 seconds, irrespective of the timeout action, after the specified or optional timeout[2021-01-29 23:25:46,101] DEBUG - wire HTTP-Sender I/O dispatcher-1 << "GET /hello HTTP/1.1[\r][\n]"[2021-01-29 23:25:46,102] DEBUG - wire HTTP-Sender I/O dispatcher-1 << "Origin: https://localhost:9443[\r][\n]"[2021-01-29 23:25:46,102] DEBUG - wire HTTP-Sender I/O dispatcher-1 << "X-JWT-Assertion: eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.iiIRk-PhDT_l18hg0EaO6FS05_2QY4_raR-x5nScBRMWYACsZJwERlzCp75Py5iOUSQrUPnEnVGgFY-vpC-iq9UOyrQMEd74tVYuRTFDmXDW2qZQ0vN53aGUDmOiX-fGQP2rsliiVASy0EiYYP8rWTVwaqI5iNy8xS3kG0SSVA2gdRz00zXc_KqbBYehENSdebGbDoqMn6phsEDCssbvZJxD9-Wy8fVHIWQixJMc5SRyQmUGhQXmfIMKPODVHkKLrGs8KAF3qWCeByu8otaDImyDR-h4BgLnr_QoLomOqlHJDfcCKgzA2SraDoiDzIEegR6sl-67YyT_7RiTZV6yVg.1th0OhYVhTcQ9GKVbQHuYA.JdyuPPEowGYIw7ayAhbX4OvZIwxXUYmak5m-8SjqzQLH6F4GXge2C4xBebDJHslNT0rPTEypHTcDXZIovzuupDegJBvqMotoyPgUrKC9Y-guDhmQp0o6r45D-AF6DFDDcslfJLpaPzebSzf1LbFHfTCVzLa2OKhu2rComPBqmIP6C9ZWY1fNsHfwTCFt_v9zhMIrzOmSXWkG-yAxoJCY-aS9ZU8jat8QoetBLXOispt7QfPrmGeVO0aa8scMl5XpkgLN4ICUresq_Wk8ZXsW7tbnQw7RV3ar5wSWbcyGzr1LZ3rxWtTOIY8BImRMHYrUqiWdVquR0bxbQMNlQQC760ifw9WaR4ALtnTVxviOteBePQVypQ7d47nq7zOf7YnmO7R6q665JpmK2TJKSmEqAPYtwKtqpV_Ngf-PlepevdGCdnooP-ArND3jF3sxQFQ4lkKtbI7UJALzC1MzO74zvG1T3voBQce7Mktov7STFxPj8TTIDIMPL0gy1TwPFhEQyuZf6NVPGxacR7hkaWn2VlPUbs9n771fefcX-eE16cFEBGKV0qoSySS_epTh_fOlkyhfikqi1KRjSi0QdgKMPEDOhYP7mEMB1qpN_rf4kr9Ka9kOQCLZMxbSQqpKq2EfCi6ytxJRdYlUJFTdZ4Ddq7Hy7JAUTaX4Q8AeIv6bCB_4l-vGE2YH93XTIX4VcPiCnCoh8cDe7-0e3-IKbRo7RnkaOUB9vEAkb5Kx2ZwnnS61oMUUMIqO1e4V6wkjtiNbtiRp2LCijBAXSDnURif6QrtTXXWF4IiuKm8TOFP-VuiLQ-cWxLC9SYrQ4xCulTuunVPe33HAwhUENOMG4S15ZMxS7ErF_wbVOtI3EkkjE8s46j5pTWhW7PUbcWVj4ehJiTMUSP4T8YyWeSxXEAlxi0owVAaT2iSXMvT26BH2Or_w0BsLek2F5yZAMK1bd7r36W7l-1PQMpnbb0NS8tMLlA5Li2rLMS_HgiCgdMxslKHt4_zKLS-CSXQ9nlRqblggR3mgUbzd-rEKTX-YZ41mUrjDoXpD2JgcSUrzu1ds4WZkhzjv7GxvHO7dkjTSD06upZiwPE9DZ8qnN9an2QKg5lvduIjS8ZiOEAbuaP49uB3gkfQ2gSuFWY07SBdhvgw8a0I4e31eZpdbE16vXWIC4AxBfBQ4k7_4NTWCBFL6B5Y.veM5Eu0-o4dhctG6lJ9-HQ[\r][\n]"

Sample Spring REST API To Consume JWE

With this sample REST client, It will decrypt and consume the JWE token. To run that, Go inside the sampleapi project in the cloned project from github, Then go find the file JWEDecryptor.java and edit the keystore related changes appropriately. Once all changes done, run the sample.

Then we can front that sample with an API created by WSO2 API Manager. Upon a successful API invocation, This sample API will respond with the JSON object contains the claims passed via the JWE.

Hope this will help you if you need to pass end user claims when using WSO2 API Manager via JWE rather that the JWT token.

# /bin/bashecho '! Happy Coding'

--

--