From 0dc9fd0a8da62b0a71e18c7b77fd536138755845 Mon Sep 17 00:00:00 2001 From: James Anderson Date: Fri, 3 Sep 2021 11:09:42 -0500 Subject: [PATCH] Serialize audience claim when a List --- .../com/auth0/jwt/impl/PayloadSerializer.java | 70 +++++++++++-------- .../auth0/jwt/impl/PayloadSerializerTest.java | 59 ++++++++++++++-- 2 files changed, 95 insertions(+), 34 deletions(-) diff --git a/lib/src/main/java/com/auth0/jwt/impl/PayloadSerializer.java b/lib/src/main/java/com/auth0/jwt/impl/PayloadSerializer.java index 684137cc..8a86c04a 100644 --- a/lib/src/main/java/com/auth0/jwt/impl/PayloadSerializer.java +++ b/lib/src/main/java/com/auth0/jwt/impl/PayloadSerializer.java @@ -5,8 +5,7 @@ import com.fasterxml.jackson.databind.ser.std.StdSerializer; import java.io.IOException; -import java.util.Date; -import java.util.Map; +import java.util.*; /** * Jackson serializer implementation for converting into JWT Payload parts. @@ -30,40 +29,51 @@ public void serialize(ClaimsHolder holder, JsonGenerator gen, SerializerProvider gen.writeStartObject(); for (Map.Entry e : holder.getClaims().entrySet()) { - switch (e.getKey()) { - case PublicClaims.AUDIENCE: - if (e.getValue() instanceof String) { - gen.writeFieldName(e.getKey()); - gen.writeString((String) e.getValue()); - break; - } - String[] audArray = (String[]) e.getValue(); - if (audArray.length == 1) { - gen.writeFieldName(e.getKey()); - gen.writeString(audArray[0]); - } else if (audArray.length > 1) { - gen.writeFieldName(e.getKey()); - gen.writeStartArray(); - for (String aud : audArray) { - gen.writeString(aud); - } - gen.writeEndArray(); - } - break; - default: - gen.writeFieldName(e.getKey()); - if (e.getValue() instanceof Date) { // true for EXPIRES_AT, ISSUED_AT, NOT_BEFORE - gen.writeNumber(dateToSeconds((Date) e.getValue())); - } else { - gen.writeObject(e.getValue()); - } - break; + if (PublicClaims.AUDIENCE.equals(e.getKey())) { + writeAudience(gen, e); + } else { + gen.writeFieldName(e.getKey()); + if (e.getValue() instanceof Date) { // true for EXPIRES_AT, ISSUED_AT, NOT_BEFORE + gen.writeNumber(dateToSeconds((Date) e.getValue())); + } else { + gen.writeObject(e.getValue()); + } } } gen.writeEndObject(); } + private void writeAudience(JsonGenerator gen, Map.Entry e) throws IOException { + if (e.getValue() instanceof String) { + gen.writeFieldName(e.getKey()); + gen.writeString((String) e.getValue()); + } else { + List audArray = new ArrayList<>(); + if (e.getValue() instanceof String[]) { + audArray = Arrays.asList((String[]) e.getValue()); + } else if (e.getValue() instanceof List) { + List audList = (List) e.getValue(); + for (Object aud : audList) { + if (aud instanceof String) { + audArray.add((String)aud); + } + } + } + if (audArray.size() == 1) { + gen.writeFieldName(e.getKey()); + gen.writeString(audArray.get(0)); + } else if (audArray.size() > 1) { + gen.writeFieldName(e.getKey()); + gen.writeStartArray(); + for (String aud : audArray) { + gen.writeString(aud); + } + gen.writeEndArray(); + } + } + } + private long dateToSeconds(Date date) { return date.getTime() / 1000; } diff --git a/lib/src/test/java/com/auth0/jwt/impl/PayloadSerializerTest.java b/lib/src/test/java/com/auth0/jwt/impl/PayloadSerializerTest.java index ebdd5864..3ebc29dd 100644 --- a/lib/src/test/java/com/auth0/jwt/impl/PayloadSerializerTest.java +++ b/lib/src/test/java/com/auth0/jwt/impl/PayloadSerializerTest.java @@ -9,10 +9,7 @@ import org.junit.Test; import java.io.StringWriter; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertThat; @@ -80,6 +77,60 @@ public void shouldSkipSerializationOnEmptyAudience() throws Exception { assertThat(writer.toString(), is(equalTo("{}"))); } + @Test + public void shouldSerializeSingleItemAudienceAsArrayWhenAList() throws Exception { + ClaimsHolder holder = holderFor("aud", Collections.singletonList("auth0")); + serializer.serialize(holder, jsonGenerator, serializerProvider); + jsonGenerator.flush(); + + assertThat(writer.toString(), is(equalTo("{\"aud\":\"auth0\"}"))); + } + + @Test + public void shouldSerializeMultipleItemsAudienceAsArrayWhenAList() throws Exception { + ClaimsHolder holder = holderFor("aud", Arrays.asList("auth0", "auth10")); + serializer.serialize(holder, jsonGenerator, serializerProvider); + jsonGenerator.flush(); + + assertThat(writer.toString(), is(equalTo("{\"aud\":[\"auth0\",\"auth10\"]}"))); + } + + @Test + public void shouldSkipSerializationOnEmptyAudienceWhenList() throws Exception { + ClaimsHolder holder = holderFor("aud", new ArrayList()); + serializer.serialize(holder, jsonGenerator, serializerProvider); + jsonGenerator.flush(); + + assertThat(writer.toString(), is(equalTo("{}"))); + } + + @Test + public void shouldSkipNonStringsOnAudienceWhenSingleItemList() throws Exception { + ClaimsHolder holder = holderFor("aud", Collections.singletonList(2)); + serializer.serialize(holder, jsonGenerator, serializerProvider); + jsonGenerator.flush(); + + assertThat(writer.toString(), is(equalTo("{}"))); + } + + @Test + public void shouldSkipNonStringsOnAudienceWhenList() throws Exception { + ClaimsHolder holder = holderFor("aud", Arrays.asList("auth0", 2, "auth10")); + serializer.serialize(holder, jsonGenerator, serializerProvider); + jsonGenerator.flush(); + + assertThat(writer.toString(), is(equalTo("{\"aud\":[\"auth0\",\"auth10\"]}"))); + } + + @Test + public void shouldSkipNonStringsOnAudience() throws Exception { + ClaimsHolder holder = holderFor("aud", 4); + serializer.serialize(holder, jsonGenerator, serializerProvider); + jsonGenerator.flush(); + + assertThat(writer.toString(), is(equalTo("{}"))); + } + @Test public void shouldSerializeNotBeforeDateInSeconds() throws Exception { ClaimsHolder holder = holderFor("nbf", new Date(1478874000));