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