[fpjwt] TClaims.AsEncodedString returns the wrong value

Version tested:_ Lazarus 4.99 (rev main_4_99-4053-g2d834c7071) FPC 3.3.1 x86_64-win64-win32/win64_

When you compile and run fpcsrc\packages\fcl-web\examples\jwt\signrs256.lpr, the following JWT token is returned:

eyAidHlwIiA6ICJKV1QiLCAiYWxnIiA6ICJSUzI1NiIgfQ.eyAiYXVkIiA6ICIiIH0.oY4y9A-IhtzqHKDSAHsH4X-wOTV2NbMzuzU88CeJmIWzrPA0BEBHbiVYf3LLdCYX4pKSBunPqNaBixpwpNziGrq22MfZyHC7_iSO4Wkw1P0QI6H_USVWY57DFhEfYQjUwwH7BwLo2ETLDPzg5JMpnlTnQ_9AdKUUiSIuqUwT-YHDa3oGXJ7n5-cZuc_HEM-ve51Y34nZf520GXAi9ZfqU2jyJWEs8f3lT6kTRw0oW3bG02P69nIPI4Cd9tC4J-KgPCo1-OZN3r9gua-O80gcBln8CKa1TxltIvTxMgBgI0e6ZVT_kW7rrPwcJU7UQknK1tu41e501HioOt7IBdW9cg

If you put this JWT token into a token validator (like https://www.jwt.io), you will see that the decoded payload for the claims section is {"aud": ""}. This happens because the base64-encoding of the claims payload is eyAiYXVkIiA6ICIiIH0. However, in the signrs256.lpr application, we are expecting to see the following fields in the claims: sub, iat, exp, iss, admin, and Name. aud is not even one of them.

I propose a patch that fixes this issue:

fix-TClaims.AsEncodedString-returns-the-wrong-value.patch

When running the application with my patch, we get the following JWT token:

eyAidHlwIiA6ICJKV1QiLCAiYWxnIiA6ICJSUzI1NiIgfQ.eyAiaXNzIiA6ICJGUEMgSldUIiwgInN1YiIgOiAiMTIzNDU2Nzg5MCIsICJleHAiIDogMTc3NjYxNjQxNSwgImlhdCIgOiAxNTE2MjM5MDIyLCAiTmFtZSIgOiAiSm9obiBEb2UiLCAiYWRtaW4iIDogZmFsc2UgfQ.KfDLPAIZybBPizPC-uL8AjjcN7micDNr_Jj6vvDHShTXAHfjVAfzytf4SB5jVBm45LadHMK5UO54DcAGmS68Vog7STL0dggo5IVtGFUe_5gCmT74r1KyBJp5-6XVjQ6vocOptpEh850B4cgJEh31lLVoy9oLZam_c05zJVakeejU9DcfUcWQDAW88M62J4E3DRapBy4ZF3ZG1D0kKxsTOGFuHlZCgAiyhtshwH4cxnfAjg04kLXgBBG6ypbgR1hZpEdrRkGYMabAMjwvT8CT1fJvz2xjGRSF6FjCWmUM5MF6j4_U1FkRp2_RGIAJvj7ber6VIMygmuqPSIqagG6a7A

When the claims section is decoded, we get the expected payload:

{"iss": "FPC JWT", "sub": "1234567890", "exp": 1776616415, "iat": 1516239022, "Name": "John Doe", "admin": false}

This JWT token passes signature verification with the certificate found in the signrs256.lpr application:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvkRfGW8psCZ3G4+hBA6W
/CR/FHhBLB3k3QLypamPbRFlFBxLtOK2NblBybY22vUiMLZbb5x8OoOj/IhOrJAl
TqhtbTWLy/0K3qbG09vLm8V40kEK8/p0STrp3UmsxHNkccj9MRSKk7pOyEvxSCY6
K5JGK1VTsMuDCS7DCYk6Vqr3zjX7qedF1PVM+Z5t0B+f//kt3oBETNlic4IooEpG
/PN2GUQ0oZpa16DDtfgGu7wT3X3QEZFWLJYQTvGc82NpachBIUvqNdIt1npbK38M
XU4IPHVrSN/HdK2nQPSMLdKnTV+Eh/HcxpfjBjarg+VjgDqlmqJ9bkosOVn35vsg
8wIDAQAB
-----END PUBLIC KEY-----

Note that in the original code, the value of aud was output even if the field was empty. This behavior was changed in the patch, since RFC 7519 specifies that the field is optional.

Edited by Pascal Bergeron