fpjwt cannot process JWT tokens when audience is an array - EJSON exception "Cannot convert data from array value" raised
Summary
TClaims implement aud as a string.
TClaims = Class(TBaseJWT)
private
FAud: String; //Bug: this could be an array of strings, and usually is
FExp: Int64;
FIat: Int64;
FIss: String;
FJTI: String;
FNbf: Int64;
FSub: String;
Published
// Registered Claim Names. Keep the case lowercase, the RTTI must match the registered name.
Property iss : String Read FIss Write FIss;
Property sub : String Read FSub Write FSub;
Property aud : String Read FAud Write FAud; //Bug: this could be an array of strings, and usually is
Property exp : Int64 Read FExp Write FExp;
Property nbf : Int64 Read FNbf Write FNbf;
Property iat : Int64 Read FIat Write FIat;
Property jti : String Read FJTI Write FJTI;
end;
But RFC 7519 (https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3) states: "In the general case, the "aud" value is an array of case-sensitive strings, each containing a StringOrURI value. In the special case when the JWT has one audience, the "aud" value MAY be a single case-sensitive string containing a StringOrURI value."
For example Keycloak 24+ returns a token like:
{
"exp": 1743759752,
"iat": 1743759452,
"auth_time": 1743759451,
"jti": "fccaf7dc-bebb-46ae-8d94-8fccc11a697f",
"iss": "https://www.example.com/realms/myrealm",
"aud": [
"myaud_1",
"myaud_2",
"myaud_3",
"account"
],
"sub": "172bd0d2-8d4a-4ed7-9d7a-81a5c104dad7",
"typ": "Bearer",
"azp": "myapp",
"nonce": "8624221b-4683-4d05-867b-0077fadc2b56",
"session_state": "5acb3131-4393-4883-b08a-31ce77184092",
System Information
- Ubuntu 22 LTS
- x86-64
- FPC 3.3.1
- Computer
Steps to reproduce
This simple code:
var
AuthHdr: string; // Keycloak issued token
JWTData: TJWT;
PubKey: string; // Keycloak public key
JWTData := TJWT.ValidateJWT(AuthHdr, TJWTKey.Create(PemToDER(PubKey, '', '')));
Will rise a EJSON exception when trying to validate the token, since it can process the aud field correctly.
Example Project
What is the current bug behavior?
EJSON exception raised "Cannot convert data from array value".
What is the expected (correct) behavior?
No exception is raised and the "aud" field is processed and filled correctly, containing all audiences - that's needed to check if the call can be processed or not.