Merge branch '7.0.x'

This commit is contained in:
Josh Cummings 2026-03-31 15:56:49 -06:00
commit cb129d6b2d
No known key found for this signature in database
GPG Key ID: 869B37A20E876129
39 changed files with 202 additions and 9 deletions

View File

@ -35,6 +35,7 @@ import org.springframework.security.web.FilterInvocation;
*/
@Deprecated
@NullUnmarked
@SuppressWarnings("serial")
class WebExpressionConfigAttribute implements ConfigAttribute, EvaluationContextPostProcessor<FilterInvocation> {
private final Expression authorizeExpression;

View File

@ -48,6 +48,7 @@ import org.springframework.security.jackson.SecurityJacksonModules;
* @since 7.0
* @see SecurityJacksonModules
*/
@SuppressWarnings("serial")
public class CasJacksonModule extends SecurityJacksonModule {
public CasJacksonModule() {

View File

@ -86,6 +86,9 @@ import org.springframework.security.authentication.password.CompromisedPasswordE
import org.springframework.security.authorization.AuthorityAuthorizationDecision;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationDeniedException;
import org.springframework.security.authorization.FactorAuthorizationDecision;
import org.springframework.security.authorization.RequiredFactor;
import org.springframework.security.authorization.RequiredFactorError;
import org.springframework.security.authorization.event.AuthorizationEvent;
import org.springframework.security.authorization.event.AuthorizationGrantedEvent;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
@ -162,6 +165,7 @@ import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.security.oauth2.jwt.JwtValidationException;
import org.springframework.security.oauth2.jwt.TestJwts;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadata;
import org.springframework.security.oauth2.server.authorization.OAuth2ClientRegistration;
@ -169,15 +173,22 @@ import org.springframework.security.oauth2.server.authorization.OAuth2TokenIntro
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationException;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientRegistrationAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2DeviceAuthorizationConsentAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2DeviceAuthorizationRequestAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2DeviceCodeAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2DeviceVerificationAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2PushedAuthorizationRequestAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2RefreshTokenAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeActor;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeCompositeAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenIntrospectionAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenRevocationAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
@ -191,6 +202,7 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimNames;
import org.springframework.security.oauth2.server.resource.BearerTokenError;
import org.springframework.security.oauth2.server.resource.BearerTokenErrors;
import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
@ -251,6 +263,7 @@ import org.springframework.security.web.webauthn.api.AuthenticationExtensionsCli
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.AuthenticatorAttestationResponse;
import org.springframework.security.web.webauthn.api.AuthenticatorSelectionCriteria;
import org.springframework.security.web.webauthn.api.AuthenticatorTransport;
import org.springframework.security.web.webauthn.api.Bytes;
@ -271,6 +284,7 @@ import org.springframework.security.web.webauthn.api.PublicKeyCredentialType;
import org.springframework.security.web.webauthn.api.PublicKeyCredentialUserEntity;
import org.springframework.security.web.webauthn.api.ResidentKeyRequirement;
import org.springframework.security.web.webauthn.api.TestAuthenticationAssertionResponses;
import org.springframework.security.web.webauthn.api.TestAuthenticatorAttestationResponses;
import org.springframework.security.web.webauthn.api.TestBytes;
import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialCreationOptions;
import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialRequestOptions;
@ -445,6 +459,8 @@ final class SerializationSamples {
generatorByClassName.put(RegisteredClient.class, (r) -> registeredClient);
generatorByClassName.put(OAuth2Authorization.class, (r) -> authorization);
generatorByClassName.put(OAuth2Authorization.Token.class, (r) -> authorization.getAccessToken());
generatorByClassName.put(OAuth2AuthorizationCode.class,
(r) -> new OAuth2AuthorizationCode("code", Instant.now(), Instant.now().plusSeconds(300)));
generatorByClassName.put(OAuth2AuthorizationConsent.class,
(r) -> OAuth2AuthorizationConsent.withId("registeredClientId", "principalName")
.scope("scope1")
@ -470,6 +486,58 @@ final class SerializationSamples {
authenticationToken.setDetails(details);
return authenticationToken;
});
generatorByClassName.put(
org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeAuthenticationToken.class,
(r) -> {
org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeAuthenticationToken token = new org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeAuthenticationToken(
"code", principal, "https://localhost/callback", Map.of("custom_param", "custom_value"));
token.setDetails(details);
return token;
});
generatorByClassName.put(OAuth2AuthorizationCodeRequestAuthenticationException.class, (r) -> {
OAuth2AuthorizationCodeRequestAuthenticationToken authToken = new OAuth2AuthorizationCodeRequestAuthenticationToken(
"https://localhost/authorize", "clientId", principal, "https://localhost/callback", "state",
authorizationRequest.getScopes(), authorizationRequest.getAdditionalParameters());
return new OAuth2AuthorizationCodeRequestAuthenticationException(
new OAuth2Error("invalid_request", "Missing required parameter", "https://example.com/error"),
authToken);
});
generatorByClassName.put(OAuth2ClientCredentialsAuthenticationToken.class, (r) -> {
OAuth2ClientCredentialsAuthenticationToken token = new OAuth2ClientCredentialsAuthenticationToken(principal,
Set.of("scope1", "scope2"), Map.of("custom_param", "custom_value"));
token.setDetails(details);
return token;
});
generatorByClassName.put(OAuth2DeviceCodeAuthenticationToken.class, (r) -> {
OAuth2DeviceCodeAuthenticationToken token = new OAuth2DeviceCodeAuthenticationToken("device-code",
principal, Map.of("custom_param", "custom_value"));
token.setDetails(details);
return token;
});
generatorByClassName.put(OAuth2RefreshTokenAuthenticationToken.class, (r) -> {
OAuth2RefreshTokenAuthenticationToken token = new OAuth2RefreshTokenAuthenticationToken("refresh-token",
principal, Set.of("scope1", "scope2"), Map.of("custom_param", "custom_value"));
token.setDetails(details);
return token;
});
generatorByClassName.put(OAuth2TokenExchangeAuthenticationToken.class, (r) -> {
OAuth2TokenExchangeAuthenticationToken token = new OAuth2TokenExchangeAuthenticationToken(
"urn:ietf:params:oauth:token-type:access_token", "subject-token",
"urn:ietf:params:oauth:token-type:jwt", principal, "actor-token",
"urn:ietf:params:oauth:token-type:jwt", Set.of("https://resource.example.com"), Set.of("audience"),
Set.of("scope1"), Map.of("custom_param", "custom_value"));
token.setDetails(details);
return token;
});
OAuth2TokenExchangeActor actor = new OAuth2TokenExchangeActor(Map.of(OAuth2TokenClaimNames.ISS,
"https://issuer.example.com", OAuth2TokenClaimNames.SUB, "actor-subject"));
generatorByClassName.put(OAuth2TokenExchangeActor.class, (r) -> actor);
generatorByClassName.put(OAuth2TokenExchangeCompositeAuthenticationToken.class, (r) -> {
AbstractAuthenticationToken token = new OAuth2TokenExchangeCompositeAuthenticationToken(authentication,
List.of(actor));
token.setDetails(details);
return token;
});
generatorByClassName.put(OAuth2AuthorizationConsentAuthenticationToken.class, (r) -> {
OAuth2AuthorizationConsentAuthenticationToken authenticationToken = new OAuth2AuthorizationConsentAuthenticationToken(
"authorizationUri", "clientId", principal, "state", authorizationRequest.getScopes(),
@ -685,6 +753,12 @@ final class SerializationSamples {
generatorByClassName.put(AuthorizationDecision.class, (r) -> new AuthorizationDecision(true));
generatorByClassName.put(AuthorityAuthorizationDecision.class,
(r) -> new AuthorityAuthorizationDecision(true, AuthorityUtils.createAuthorityList("ROLE_USER")));
RequiredFactor factor = RequiredFactor.withAuthority("authority").validDuration(Duration.ofSeconds(5)).build();
generatorByClassName.put(RequiredFactor.class, (r) -> factor);
RequiredFactorError error = RequiredFactorError.createMissing(factor);
generatorByClassName.put(RequiredFactorError.class, (r) -> error);
generatorByClassName.put(FactorAuthorizationDecision.class,
(r) -> new FactorAuthorizationDecision(List.of(error)));
generatorByClassName.put(CycleInRoleHierarchyException.class, (r) -> new CycleInRoleHierarchyException());
generatorByClassName.put(AuthorizationEvent.class,
(r) -> new AuthorizationEvent(new SerializableSupplier<>(authentication), "source",
@ -875,6 +949,8 @@ final class SerializationSamples {
generatorByClassName.put(CredentialPropertiesOutput.class, (o) -> credentialOutput);
generatorByClassName.put(ImmutableAuthenticationExtensionsClientOutputs.class, (o) -> outputs);
generatorByClassName.put(AuthenticatorAssertionResponse.class, (r) -> response);
generatorByClassName.put(AuthenticatorAttestationResponse.class,
(r) -> TestAuthenticatorAttestationResponses.createAuthenticatorAttestationResponse().build());
generatorByClassName.put(RelyingPartyAuthenticationRequest.class, (r) -> authRequest);
generatorByClassName.put(PublicKeyCredential.class, (r) -> credential);
generatorByClassName.put(WebAuthnAuthenticationRequestToken.class, (r) -> requestToken);

View File

@ -33,10 +33,10 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import org.apache.commons.lang3.ObjectUtils;
@ -207,10 +207,7 @@ class SpringSecurityCoreVersionSerializableTests {
boolean hasSerialVersion = Stream.of(clazz.getDeclaredFields())
.map(Field::getName)
.anyMatch((n) -> n.equals("serialVersionUID"));
SuppressWarnings suppressWarnings = clazz.getAnnotation(SuppressWarnings.class);
boolean hasSerialIgnore = suppressWarnings == null
|| Arrays.asList(suppressWarnings.value()).contains("Serial");
if (!hasSerialVersion && !hasSerialIgnore) {
if (!hasSerialVersion && !hasSuppressSerialInSource(clazz)) {
classes.add(clazz);
continue;
}
@ -249,6 +246,58 @@ class SpringSecurityCoreVersionSerializableTests {
return classes.stream();
}
private static boolean hasSuppressSerialInSource(Class<?> clazz) {
try {
Class<?> fileClass = clazz;
while (fileClass.getEnclosingClass() != null) {
fileClass = fileClass.getEnclosingClass();
}
var codeSource = fileClass.getProtectionDomain().getCodeSource();
if (codeSource == null) {
return false;
}
Path sourceFile = findSourceFile(Path.of(codeSource.getLocation().toURI()), fileClass);
if (sourceFile == null) {
return false;
}
return hasSuppressSerialAnnotation(Files.readAllLines(sourceFile), clazz.getSimpleName());
}
catch (Exception ex) {
return false;
}
}
private static Path findSourceFile(Path start, Class<?> clazz) {
String relativePath = clazz.getName().replace('.', '/') + ".java";
Path dir = start;
for (int i = 0; i < 10 && dir != null; i++) {
for (String sourceRoot : List.of("src/main/java", "src/test/java")) {
Path candidate = dir.resolve(sourceRoot).resolve(relativePath);
if (Files.exists(candidate)) {
return candidate;
}
}
dir = dir.getParent();
}
return null;
}
private static boolean hasSuppressSerialAnnotation(List<String> lines, String simpleClassName) {
Pattern classDeclaration = Pattern
.compile("\\b(?:class|interface|enum|record)\\s+" + Pattern.quote(simpleClassName) + "\\b");
for (int i = 0; i < lines.size(); i++) {
if (classDeclaration.matcher(lines.get(i)).find()) {
for (int j = Math.max(0, i - 5); j < i; j++) {
String line = lines.get(j);
if (line.contains("@SuppressWarnings") && line.contains("\"serial\"")) {
return true;
}
}
}
}
return false;
}
private static String getCurrentVersion() {
String version = System.getProperty("springSecurityVersion");
String[] parts = version.split("\\.");

View File

@ -16,6 +16,7 @@
package org.springframework.security.authorization;
import java.io.Serial;
import java.util.Collections;
import java.util.List;
@ -29,6 +30,9 @@ import org.springframework.util.Assert;
*/
public class FactorAuthorizationDecision implements AuthorizationResult {
@Serial
private static final long serialVersionUID = -245342816437885039L;
private final List<RequiredFactorError> factorErrors;
/**

View File

@ -16,6 +16,8 @@
package org.springframework.security.authorization;
import java.io.Serial;
import java.io.Serializable;
import java.time.Duration;
import java.util.Objects;
@ -40,7 +42,10 @@ import org.springframework.util.Assert;
* @author Rob Winch
* @since 7.0
*/
public final class RequiredFactor {
public final class RequiredFactor implements Serializable {
@Serial
private static final long serialVersionUID = 295501208651764485L;
private final String authority;

View File

@ -16,6 +16,8 @@
package org.springframework.security.authorization;
import java.io.Serial;
import java.io.Serializable;
import java.util.Objects;
import org.jspecify.annotations.Nullable;
@ -29,7 +31,10 @@ import org.springframework.util.Assert;
* @author Rob Winch
* @since 7.0
*/
public class RequiredFactorError {
public class RequiredFactorError implements Serializable {
@Serial
private static final long serialVersionUID = 1946221547278528901L;
private final RequiredFactor requiredFactor;

View File

@ -16,6 +16,7 @@
package org.springframework.security.authentication;
@SuppressWarnings("serial")
public class NonBuildableAuthenticationToken extends TestingAuthenticationToken {
public NonBuildableAuthenticationToken(String user, String password, String... authorities) {

View File

@ -225,6 +225,7 @@ public final class InMemoryOAuth2AuthorizationService implements OAuth2Authoriza
return userCode != null && userCode.getToken().getTokenValue().equals(token);
}
@SuppressWarnings("serial")
private static final class MaxSizeHashMap<K, V> extends LinkedHashMap<K, V> {
private final int maxSize;

View File

@ -16,6 +16,7 @@
package org.springframework.security.oauth2.server.authorization;
import java.io.Serial;
import java.time.Instant;
import org.springframework.security.oauth2.core.AbstractOAuth2Token;
@ -32,6 +33,9 @@ import org.springframework.security.oauth2.core.AbstractOAuth2Token;
*/
public class OAuth2AuthorizationCode extends AbstractOAuth2Token {
@Serial
private static final long serialVersionUID = 3789328028057414501L;
/**
* Constructs an {@code OAuth2AuthorizationCode} using the provided parameters.
* @param tokenValue the token value

View File

@ -16,6 +16,7 @@
package org.springframework.security.oauth2.server.authorization.authentication;
import java.io.Serial;
import java.util.Map;
import org.jspecify.annotations.Nullable;
@ -37,6 +38,9 @@ import org.springframework.util.Assert;
*/
public class OAuth2AuthorizationCodeAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken {
@Serial
private static final long serialVersionUID = 4629166286850598162L;
private final String code;
private final @Nullable String redirectUri;

View File

@ -16,8 +16,9 @@
package org.springframework.security.oauth2.server.authorization.authentication;
import org.jspecify.annotations.Nullable;
import java.io.Serial;
import org.springframework.lang.Nullable;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
@ -34,6 +35,9 @@ import org.springframework.security.oauth2.core.OAuth2Error;
*/
public class OAuth2AuthorizationCodeRequestAuthenticationException extends OAuth2AuthenticationException {
@Serial
private static final long serialVersionUID = -3791188557904282453L;
private final @Nullable OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication;
/**

View File

@ -16,6 +16,7 @@
package org.springframework.security.oauth2.server.authorization.authentication;
import java.io.Serial;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
@ -37,6 +38,9 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType;
*/
public class OAuth2ClientCredentialsAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken {
@Serial
private static final long serialVersionUID = -220223451609576578L;
private final Set<String> scopes;
/**

View File

@ -16,6 +16,7 @@
package org.springframework.security.oauth2.server.authorization.authentication;
import java.io.Serial;
import java.util.Map;
import org.jspecify.annotations.Nullable;
@ -35,6 +36,9 @@ import org.springframework.util.Assert;
*/
public class OAuth2DeviceCodeAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken {
@Serial
private static final long serialVersionUID = 8364555864666204030L;
private final String deviceCode;
/**

View File

@ -16,6 +16,7 @@
package org.springframework.security.oauth2.server.authorization.authentication;
import java.io.Serial;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
@ -37,6 +38,9 @@ import org.springframework.util.Assert;
*/
public class OAuth2RefreshTokenAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken {
@Serial
private static final long serialVersionUID = 328697547826078993L;
private final String refreshToken;
private final Set<String> scopes;

View File

@ -16,6 +16,8 @@
package org.springframework.security.oauth2.server.authorization.authentication;
import java.io.Serial;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
@ -33,7 +35,10 @@ import org.springframework.util.Assert;
* @since 7.0
* @see OAuth2TokenExchangeCompositeAuthenticationToken
*/
public final class OAuth2TokenExchangeActor implements ClaimAccessor {
public final class OAuth2TokenExchangeActor implements ClaimAccessor, Serializable {
@Serial
private static final long serialVersionUID = -3966261411784615574L;
private final Map<String, Object> claims;

View File

@ -16,6 +16,7 @@
package org.springframework.security.oauth2.server.authorization.authentication;
import java.io.Serial;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
@ -38,6 +39,9 @@ import org.springframework.util.Assert;
*/
public class OAuth2TokenExchangeAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken {
@Serial
private static final long serialVersionUID = 2484741634669297785L;
private final String requestedTokenType;
private final String subjectToken;

View File

@ -16,6 +16,7 @@
package org.springframework.security.oauth2.server.authorization.authentication;
import java.io.Serial;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -37,6 +38,9 @@ import org.springframework.util.Assert;
*/
public class OAuth2TokenExchangeCompositeAuthenticationToken extends AbstractAuthenticationToken {
@Serial
private static final long serialVersionUID = 1912280308201180854L;
private final Authentication subject;
private final List<OAuth2TokenExchangeActor> actors;

View File

@ -155,6 +155,7 @@ public final class OAuth2AccessTokenGenerator implements OAuth2TokenGenerator<OA
this.clock = clock;
}
@SuppressWarnings("serial")
private static final class OAuth2AccessTokenClaims extends OAuth2AccessToken implements ClaimAccessor {
private final Map<String, Object> claims;

View File

@ -268,6 +268,7 @@ public class OAuth2AuthorizationRequestRedirectFilter extends OncePerRequestFilt
}
@SuppressWarnings("serial")
private static final class OAuth2AuthorizationRequestException extends AuthenticationException {
OAuth2AuthorizationRequestException(Throwable cause) {

View File

@ -23,6 +23,7 @@ import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames
/**
* @author Joe Grandja
*/
@SuppressWarnings("serial")
public class TestOidcAuthorizationRequest extends OAuth2AuthorizationRequest {
private final String nonce;

View File

@ -185,6 +185,7 @@ public final class DPoPProofJwtDecoderFactory implements JwtDecoderFactory<DPoPP
return Base64.getUrlEncoder().withoutPadding().encodeToString(digest);
}
@SuppressWarnings("serial")
private static final class JtiCache extends LinkedHashMap<String, Long> {
private static final int MAX_SIZE = 1000;

View File

@ -16,6 +16,7 @@
package org.springframework.security.saml2.provider.service.authentication;
import java.io.Serial;
import java.util.Collections;
import org.jspecify.annotations.Nullable;
@ -35,6 +36,9 @@ import org.springframework.util.Assert;
*/
public class Saml2AuthenticationToken extends AbstractAuthenticationToken {
@Serial
private static final long serialVersionUID = 5225098478444036532L;
private final RelyingPartyRegistration relyingPartyRegistration;
private final String saml2Response;

View File

@ -25,6 +25,7 @@ import org.springframework.security.core.GrantedAuthority;
* @author Rob Winch
* @since 7.0
*/
@SuppressWarnings("serial")
public class DefaultEqualsGrantedAuthority implements GrantedAuthority {
public static final String AUTHORITY = "CUSTOM_AUTHORITY";

View File

@ -16,6 +16,7 @@
package org.springframework.security.web.webauthn.api;
import java.io.Serial;
import java.util.Arrays;
import java.util.List;
@ -36,6 +37,9 @@ import org.jspecify.annotations.Nullable;
*/
public final class AuthenticatorAttestationResponse extends AuthenticatorResponse {
@Serial
private static final long serialVersionUID = -1628559840895428945L;
private final Bytes attestationObject;
private final @Nullable List<AuthenticatorTransport> transports;