spring-projects / spring-security

Spring Security
http://spring.io/projects/spring-security
Apache License 2.0
8.72k stars 5.86k forks source link

OidcIdToken can not be deserialized with jackson #12917

Closed vdiskg closed 3 months ago

vdiskg commented 1 year ago

Describe the bug when claims contains a value of java.lang.Long, java.lang.Character, java.lang.Short, java.lang.Float, java.lang.Byte, it can not be deserialized

To Reproduce

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Duration;
import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.security.oauth2.core.oidc.OidcIdToken;

class OidcIdTokenSerializeTest {

  @Test
  void idTokenSerialize() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModules(SecurityJackson2Modules.getModules(this.getClass().getClassLoader()));
    Map<String, Object> claims = new LinkedHashMap<>();
    claims.put("long", 1L);
    claims.put("char", 'a');
    claims.put("short", (short) 1);
    claims.put("float", 1.0f);
    claims.put("byte", (byte) 1);

    OidcIdToken idToken = new OidcIdToken("id", Instant.now(),
        Instant.now().plus(Duration.ofSeconds(10)), claims);
    String string = mapper.writeValueAsString(idToken);
    OidcIdToken oidcIdToken = mapper.readValue(string, OidcIdToken.class);// exception occurs here
  }
}

Expected behavior no occurs exception when deserialized.

sjohnr commented 3 months ago

@vdiskg thanks for reaching out!

when claims contains a value of java.lang.Long, java.lang.Character, java.lang.Short, java.lang.Float, java.lang.Byte, it can not be deserialized

OidcIdToken#claims should contain standard claims from OpenID Connect Core 1.0, Section 2. Further, all claims should be standard JSON properties according to RFC 8259. The Java types you have in this test are not standard JSON types. Those would be types such as java.lang.Boolean, java.lang.String, java.lang.Integer, and java.lang.Double as well as arrays and objects which would map to java.util.ArrayList and java.util.HashMap. All such values work fine in the claims property.

If you are programmatically creating an OidcIdToken with non-standard claims, you will need to provide your own mixin(s) for those types, since Spring Security is not intending to provide a general-purpose JSON serialization library.

I'm going to close this issue with the above explanation. If you have additional context that you feel I am missing in my explanation, please let me know.