diff --git a/config/src/test/java/org/springframework/security/SerializationSamples.java b/config/src/test/java/org/springframework/security/SerializationSamples.java index 4bf96f0ccd..4974eb3985 100644 --- a/config/src/test/java/org/springframework/security/SerializationSamples.java +++ b/config/src/test/java/org/springframework/security/SerializationSamples.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.Serializable; import java.lang.reflect.Field; import java.security.Principal; +import java.time.Duration; import java.time.Instant; import java.util.Collection; import java.util.Date; @@ -245,32 +246,11 @@ import org.springframework.security.web.savedrequest.SimpleSavedRequest; import org.springframework.security.web.server.firewall.ServerExchangeRejectedException; import org.springframework.security.web.session.HttpSessionCreatedEvent; import org.springframework.security.web.session.HttpSessionIdChangedEvent; -import org.springframework.security.web.webauthn.api.AuthenticationExtensionsClientInputs; -import org.springframework.security.web.webauthn.api.AuthenticationExtensionsClientOutputs; -import org.springframework.security.web.webauthn.api.AuthenticatorAssertionResponse; -import org.springframework.security.web.webauthn.api.AuthenticatorAttachment; -import org.springframework.security.web.webauthn.api.AuthenticatorTransport; -import org.springframework.security.web.webauthn.api.Bytes; -import org.springframework.security.web.webauthn.api.CredProtectAuthenticationExtensionsClientInput; -import org.springframework.security.web.webauthn.api.CredentialPropertiesOutput; -import org.springframework.security.web.webauthn.api.ImmutableAuthenticationExtensionsClientInput; -import org.springframework.security.web.webauthn.api.ImmutableAuthenticationExtensionsClientInputs; -import org.springframework.security.web.webauthn.api.ImmutableAuthenticationExtensionsClientOutputs; -import org.springframework.security.web.webauthn.api.ImmutablePublicKeyCredentialUserEntity; -import org.springframework.security.web.webauthn.api.PublicKeyCredential; -import org.springframework.security.web.webauthn.api.PublicKeyCredentialDescriptor; -import org.springframework.security.web.webauthn.api.PublicKeyCredentialRequestOptions; -import org.springframework.security.web.webauthn.api.PublicKeyCredentialType; -import org.springframework.security.web.webauthn.api.PublicKeyCredentialUserEntity; -import org.springframework.security.web.webauthn.api.TestAuthenticationAssertionResponses; -import org.springframework.security.web.webauthn.api.TestBytes; -import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialRequestOptions; -import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialUserEntities; -import org.springframework.security.web.webauthn.api.TestPublicKeyCredentials; -import org.springframework.security.web.webauthn.api.UserVerificationRequirement; +import org.springframework.security.web.webauthn.api.*; import org.springframework.security.web.webauthn.authentication.WebAuthnAuthentication; import org.springframework.security.web.webauthn.authentication.WebAuthnAuthenticationRequestToken; import org.springframework.security.web.webauthn.management.RelyingPartyAuthenticationRequest; +import org.springframework.security.web.webauthn.management.TestPublicKeyCredentialRpEntities; import org.springframework.util.ReflectionUtils; final class SerializationSamples { @@ -879,6 +859,37 @@ final class SerializationSamples { generatorByClassName.put(CredentialPropertiesOutput.ExtensionOutput.class, (r) -> new CredentialPropertiesOutput(true).getOutput()); + AttestationConveyancePreference attestationConveyancePreference = AttestationConveyancePreference.DIRECT; + ResidentKeyRequirement residentKeyRequirement = ResidentKeyRequirement.REQUIRED; + AuthenticatorSelectionCriteria authenticatorSelectionCriteria = AuthenticatorSelectionCriteria.builder() + .authenticatorAttachment(AuthenticatorAttachment.PLATFORM) + .residentKey(residentKeyRequirement) + .userVerification(UserVerificationRequirement.REQUIRED) + .build(); + PublicKeyCredentialParameters publicKeyCredentialParameters = PublicKeyCredentialParameters.RS256; + PublicKeyCredentialRpEntity publicKeyCredentialRpEntity = TestPublicKeyCredentialRpEntities.createRpEntity().build(); + + generatorByClassName.put(AttestationConveyancePreference.class, (r) -> attestationConveyancePreference); + generatorByClassName.put(ResidentKeyRequirement.class, (r) -> residentKeyRequirement); + generatorByClassName.put(AuthenticatorSelectionCriteria.class, (r) -> authenticatorSelectionCriteria); + generatorByClassName.put(COSEAlgorithmIdentifier.class, (r -> COSEAlgorithmIdentifier.RS256)); + generatorByClassName.put(PublicKeyCredentialParameters.class, (r) -> publicKeyCredentialParameters); + generatorByClassName.put(PublicKeyCredentialRpEntity.class, (r) -> publicKeyCredentialRpEntity); + generatorByClassName.put(PublicKeyCredentialCreationOptions.class, (o) -> TestPublicKeyCredentialCreationOptions.createPublicKeyCredentialCreationOptions() + .extensions(inputs) + .attestation(attestationConveyancePreference) + .authenticatorSelection(authenticatorSelectionCriteria) + .challenge(TestBytes.get()) + .excludeCredentials(List.of(descriptor)) + .rp(publicKeyCredentialRpEntity) + .pubKeyCredParams(publicKeyCredentialParameters) + .timeout(Duration.ofMinutes(5)) + .user(TestPublicKeyCredentialUserEntities.userEntity() + .id(TestBytes.get()) + .build()) + .build() + ); + // One-Time Token DefaultOneTimeToken oneTimeToken = new DefaultOneTimeToken(UUID.randomUUID().toString(), "user", Instant.now().plusSeconds(300)); diff --git a/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.AttestationConveyancePreference.serialized b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.AttestationConveyancePreference.serialized new file mode 100644 index 0000000000..ef40b44cca Binary files /dev/null and b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.AttestationConveyancePreference.serialized differ diff --git a/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.AuthenticatorSelectionCriteria.serialized b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.AuthenticatorSelectionCriteria.serialized new file mode 100644 index 0000000000..64b008dc31 Binary files /dev/null and b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.AuthenticatorSelectionCriteria.serialized differ diff --git a/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.COSEAlgorithmIdentifier.serialized b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.COSEAlgorithmIdentifier.serialized new file mode 100644 index 0000000000..0a61cdf3e7 Binary files /dev/null and b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.COSEAlgorithmIdentifier.serialized differ diff --git a/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.PublicKeyCredentialCreationOptions.serialized b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.PublicKeyCredentialCreationOptions.serialized new file mode 100644 index 0000000000..044a97d4fd Binary files /dev/null and b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.PublicKeyCredentialCreationOptions.serialized differ diff --git a/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.PublicKeyCredentialParameters.serialized b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.PublicKeyCredentialParameters.serialized new file mode 100644 index 0000000000..e7c04e7bb1 Binary files /dev/null and b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.PublicKeyCredentialParameters.serialized differ diff --git a/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.PublicKeyCredentialRpEntity.serialized b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.PublicKeyCredentialRpEntity.serialized new file mode 100644 index 0000000000..582daf6293 Binary files /dev/null and b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.PublicKeyCredentialRpEntity.serialized differ diff --git a/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.ResidentKeyRequirement.serialized b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.ResidentKeyRequirement.serialized new file mode 100644 index 0000000000..cb8e68daa0 Binary files /dev/null and b/config/src/test/resources/serialized/7.1.x/org.springframework.security.web.webauthn.api.ResidentKeyRequirement.serialized differ diff --git a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/AttestationConveyancePreference.java b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/AttestationConveyancePreference.java index fc8c5984e2..1241faf132 100644 --- a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/AttestationConveyancePreference.java +++ b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/AttestationConveyancePreference.java @@ -16,6 +16,9 @@ package org.springframework.security.web.webauthn.api; +import java.io.Serial; +import java.io.Serializable; + /** * WebAuthn Relying * Parties may use COSEAlgorithmIdentifier is @@ -25,7 +28,10 @@ package org.springframework.security.web.webauthn.api; * @since 6.4 * @see PublicKeyCredentialParameters#getAlg() */ -public final class COSEAlgorithmIdentifier { +public final class COSEAlgorithmIdentifier implements Serializable { + + @Serial + private static final long serialVersionUID = -4907140472964185350L; public static final COSEAlgorithmIdentifier EdDSA = new COSEAlgorithmIdentifier(-8); diff --git a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialCreationOptions.java b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialCreationOptions.java index 35c1e2f0e0..47161f950c 100644 --- a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialCreationOptions.java +++ b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialCreationOptions.java @@ -16,6 +16,8 @@ package org.springframework.security.web.webauthn.api; +import java.io.Serial; +import java.io.Serializable; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; @@ -34,7 +36,10 @@ import org.jspecify.annotations.Nullable; * @author Rob Winch * @since 6.4 */ -public final class PublicKeyCredentialCreationOptions { +public final class PublicKeyCredentialCreationOptions implements Serializable { + + @Serial + private static final long serialVersionUID = 800506727675279143L; private final PublicKeyCredentialRpEntity rp; diff --git a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialParameters.java b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialParameters.java index 4bc075b051..5503ea8d9f 100644 --- a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialParameters.java +++ b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialParameters.java @@ -16,6 +16,9 @@ package org.springframework.security.web.webauthn.api; +import java.io.Serial; +import java.io.Serializable; + /** * The PublicKeyCredentialParameters @@ -25,7 +28,10 @@ package org.springframework.security.web.webauthn.api; * @since 6.4 * @see PublicKeyCredentialCreationOptions#getPubKeyCredParams() */ -public final class PublicKeyCredentialParameters { +public final class PublicKeyCredentialParameters implements Serializable { + + @Serial + private static final long serialVersionUID = -623985171385991L; public static final PublicKeyCredentialParameters EdDSA = new PublicKeyCredentialParameters( COSEAlgorithmIdentifier.EdDSA); diff --git a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialRpEntity.java b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialRpEntity.java index 6a817c205c..20049f0fcc 100644 --- a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialRpEntity.java +++ b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/PublicKeyCredentialRpEntity.java @@ -16,6 +16,9 @@ package org.springframework.security.web.webauthn.api; +import java.io.Serial; +import java.io.Serializable; + import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; @@ -29,7 +32,10 @@ import org.springframework.util.Assert; * @author Rob Winch * @since 6.4 */ -public final class PublicKeyCredentialRpEntity { +public final class PublicKeyCredentialRpEntity implements Serializable { + + @Serial + private static final long serialVersionUID = -2741017471467698174L; private final String name; diff --git a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/ResidentKeyRequirement.java b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/ResidentKeyRequirement.java index b3f9f216a0..080940fb35 100644 --- a/webauthn/src/main/java/org/springframework/security/web/webauthn/api/ResidentKeyRequirement.java +++ b/webauthn/src/main/java/org/springframework/security/web/webauthn/api/ResidentKeyRequirement.java @@ -16,6 +16,9 @@ package org.springframework.security.web.webauthn.api; +import java.io.Serial; +import java.io.Serializable; + /** * The ResidentKeyRequirement @@ -24,7 +27,10 @@ package org.springframework.security.web.webauthn.api; * @author Rob Winch * @since 6.4 */ -public final class ResidentKeyRequirement { +public final class ResidentKeyRequirement implements Serializable { + + @Serial + private static final long serialVersionUID = 1730700608982834858L; /** * The publicKeyCredential = TestPublicKeyCredentials + .createPublicKeyCredential() + .build(); + RelyingPartyPublicKey rpPublicKey = new RelyingPartyPublicKey(publicKeyCredential, this.label); + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(out)) { + objectOutputStream.writeObject(creationOptions); + objectOutputStream.flush(); + + try (ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + ObjectInputStream objectInputStream = new ObjectInputStream(in)) { + PublicKeyCredentialCreationOptions deserialized = (PublicKeyCredentialCreationOptions) objectInputStream + .readObject(); + ImmutableRelyingPartyRegistrationRequest rpRegistrationRequest = new ImmutableRelyingPartyRegistrationRequest( + deserialized, rpPublicKey); + assertThatNoException().isThrownBy(() -> this.rpOperations.registerCredential(rpRegistrationRequest)); + } + } + } + @Test void registerCredentialWhenInternalTransportThenCredentialRecordHasTransport() { PublicKeyCredentialCreationOptions creationOptions = TestPublicKeyCredentialCreationOptions