Yubico / java-webauthn-server

Server-side Web Authentication library for Java https://www.w3.org/TR/webauthn/#rp-operations
Other
439 stars 137 forks source link

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.yubico.webauthn.data.Extensions$CredentialProperties$CredentialPropertiesOutput #333

Closed alokkulkarni closed 6 months ago

alokkulkarni commented 7 months ago

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.yubico.webauthn.data.Extensions$CredentialProperties$CredentialPropertiesOutput

using webauthn java 2.6.0 alpha version

CredentialPropertiesOutput class is marked with @Builder but still faces a parsing issue and need to add a default constructor like the ones added form CredProps class.

if passing Extensions fails on this class as Jackson is not able to parse the @JsonCreator annotation and needs a default constructor to be added to the class.

pasted above the error when parsing the val credential : PublicKeyCredential<AuthenticatorAttestationResponse, ClientRegistrationExtensionOutputs> using springboot 3 jackson.

framework - springboot 3.1.5 Java version - 17 Kotlin version - 1.9.0

emlun commented 7 months ago

Can you share the JSON value you're attempting to parse?

alokkulkarni commented 7 months ago

"extensions": { "appidExclude": null, "credProps": true, "largeBlob": null, "uvm": null }

alokkulkarni commented 7 months ago

its part of that credprops check where its checking for rk Boolean value in the static class as part of CredentialPropertiesOutput when credprops is marked as true - as above json - the rk is failing in httpmessage parsing as @JsonCreator for rk

public static class CredentialProperties {
        static final String EXTENSION_ID = "credProps";

        public CredentialProperties() {
        }

        public static final class CredentialPropertiesOutput {
            @JsonProperty("rk")
            private final Boolean rk;

            @JsonCreator
            private CredentialPropertiesOutput(@JsonProperty("rk") Boolean rk) {
                this.rk = rk;
            }

            public Optional<Boolean> getRk() {
                return Optional.ofNullable(this.rk);
            }

            @Generated
            public static CredentialPropertiesOutputBuilder builder() {
                return new CredentialPropertiesOutputBuilder();
            }

            @Generated
            public boolean equals(Object o) {
                if (o == this) {
                    return true;
                } else if (!(o instanceof CredentialPropertiesOutput)) {
                    return false;
                } else {
                    CredentialPropertiesOutput other = (CredentialPropertiesOutput)o;
                    Object this$rk = this.getRk();
                    Object other$rk = other.getRk();
                    if (this$rk == null) {
                        if (other$rk != null) {
                            return false;
                        }
                    } else if (!this$rk.equals(other$rk)) {
                        return false;
                    }

                    return true;
                }
            }
emlun commented 7 months ago

That's an extension input, not an extension output. Could you share the JSON of the PublicKeyCredential response, including extensions, that you are trying to parse?

alokkulkarni commented 7 months ago

i am sending this as blank {} empty json object...

alokkulkarni commented 7 months ago
const finishRequest = {
            flowId: settings.flowId,
            credential: {
                id: newCredentialInfo.id,
                rawId: fromByteArray(newCredentialInfo.rawId),
                type: newCredentialInfo.type,
                response: {
                    clientDataJSON: fromByteArray(newCredentialInfo.response.clientDataJSON),
                    attestationObject: fromByteArray(newCredentialInfo.response.attestationObject)
                },
                clientExtensionResults: {}
            }
emlun commented 7 months ago

There are unit tests that verify that the parser supports both empty clientExtensionResults and empty credProps outputs, so I don't think that either of those is the problem. Can you share the stack trace in full?