Mark Serialization Support for Events

Issue gh-16276
This commit is contained in:
Josh Cummings 2025-01-17 16:08:15 -07:00
parent 45da5c94b6
commit bbe4f87641
No known key found for this signature in database
GPG Key ID: 869B37A20E876129
46 changed files with 175 additions and 10 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -54,6 +54,7 @@ import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.AuthorizationServiceException;
import org.springframework.security.access.intercept.RunAsUserToken;
@ -73,16 +74,33 @@ import org.springframework.security.authentication.RememberMeAuthenticationToken
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
import org.springframework.security.authentication.event.AuthenticationFailureCredentialsExpiredEvent;
import org.springframework.security.authentication.event.AuthenticationFailureDisabledEvent;
import org.springframework.security.authentication.event.AuthenticationFailureExpiredEvent;
import org.springframework.security.authentication.event.AuthenticationFailureLockedEvent;
import org.springframework.security.authentication.event.AuthenticationFailureProviderNotFoundEvent;
import org.springframework.security.authentication.event.AuthenticationFailureProxyUntrustedEvent;
import org.springframework.security.authentication.event.AuthenticationFailureServiceExceptionEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
import org.springframework.security.authentication.event.LogoutSuccessEvent;
import org.springframework.security.authentication.jaas.JaasAuthenticationToken;
import org.springframework.security.authentication.jaas.event.JaasAuthenticationFailedEvent;
import org.springframework.security.authentication.jaas.event.JaasAuthenticationSuccessEvent;
import org.springframework.security.authentication.ott.InvalidOneTimeTokenException;
import org.springframework.security.authentication.ott.OneTimeTokenAuthenticationToken;
import org.springframework.security.authentication.password.CompromisedPasswordException;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.cas.authentication.CasAuthenticationToken;
import org.springframework.security.cas.authentication.CasServiceTicketAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.session.AbstractSessionEvent;
import org.springframework.security.core.session.ReactiveSessionInformation;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.userdetails.UserDetails;
@ -163,6 +181,8 @@ import org.springframework.security.web.authentication.rememberme.CookieTheftExc
import org.springframework.security.web.authentication.rememberme.InvalidCookieException;
import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.security.web.authentication.session.SessionFixationProtectionEvent;
import org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent;
import org.springframework.security.web.authentication.www.NonceExpiredException;
import org.springframework.security.web.csrf.CsrfException;
import org.springframework.security.web.csrf.DefaultCsrfToken;
@ -170,6 +190,7 @@ import org.springframework.security.web.csrf.InvalidCsrfTokenException;
import org.springframework.security.web.csrf.MissingCsrfTokenException;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.security.web.server.firewall.ServerExchangeRejectedException;
import org.springframework.security.web.session.HttpSessionCreatedEvent;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
@ -200,6 +221,8 @@ class SpringSecurityCoreVersionSerializableTests {
static {
UserDetails user = TestAuthentication.user();
Authentication authentication = TestAuthentication.authenticated(user);
SecurityContext securityContext = new SecurityContextImpl(authentication);
// oauth2-core
generatorByClassName.put(DefaultOAuth2User.class, (r) -> TestOAuth2Users.create());
@ -375,6 +398,37 @@ class SpringSecurityCoreVersionSerializableTests {
(r) -> new UsernameNotFoundException("error", new RuntimeException()));
generatorByClassName.put(TestingAuthenticationToken.class,
(r) -> applyDetails(new TestingAuthenticationToken("username", "password")));
generatorByClassName.put(AuthenticationFailureBadCredentialsEvent.class,
(r) -> new AuthenticationFailureBadCredentialsEvent(authentication,
new BadCredentialsException("message")));
generatorByClassName.put(AuthenticationFailureCredentialsExpiredEvent.class,
(r) -> new AuthenticationFailureCredentialsExpiredEvent(authentication,
new CredentialsExpiredException("message")));
generatorByClassName.put(AuthenticationFailureDisabledEvent.class,
(r) -> new AuthenticationFailureDisabledEvent(authentication, new DisabledException("message")));
generatorByClassName.put(AuthenticationFailureExpiredEvent.class,
(r) -> new AuthenticationFailureExpiredEvent(authentication, new AccountExpiredException("message")));
generatorByClassName.put(AuthenticationFailureLockedEvent.class,
(r) -> new AuthenticationFailureLockedEvent(authentication, new LockedException("message")));
generatorByClassName.put(AuthenticationFailureProviderNotFoundEvent.class,
(r) -> new AuthenticationFailureProviderNotFoundEvent(authentication,
new ProviderNotFoundException("message")));
generatorByClassName.put(AuthenticationFailureProxyUntrustedEvent.class,
(r) -> new AuthenticationFailureProxyUntrustedEvent(authentication,
new AuthenticationServiceException("message")));
generatorByClassName.put(AuthenticationFailureServiceExceptionEvent.class,
(r) -> new AuthenticationFailureServiceExceptionEvent(authentication,
new AuthenticationServiceException("message")));
generatorByClassName.put(AuthenticationSuccessEvent.class,
(r) -> new AuthenticationSuccessEvent(authentication));
generatorByClassName.put(InteractiveAuthenticationSuccessEvent.class,
(r) -> new InteractiveAuthenticationSuccessEvent(authentication, Authentication.class));
generatorByClassName.put(LogoutSuccessEvent.class, (r) -> new LogoutSuccessEvent(authentication));
generatorByClassName.put(JaasAuthenticationFailedEvent.class,
(r) -> new JaasAuthenticationFailedEvent(authentication, new RuntimeException("message")));
generatorByClassName.put(JaasAuthenticationSuccessEvent.class,
(r) -> new JaasAuthenticationSuccessEvent(authentication));
generatorByClassName.put(AbstractSessionEvent.class, (r) -> new AbstractSessionEvent(securityContext));
// cas
generatorByClassName.put(CasServiceTicketAuthenticationToken.class, (r) -> {
@ -448,6 +502,12 @@ class SpringSecurityCoreVersionSerializableTests {
generatorByClassName.put(RequestRejectedException.class, (r) -> new RequestRejectedException("message"));
generatorByClassName.put(ServerExchangeRejectedException.class,
(r) -> new ServerExchangeRejectedException("message"));
generatorByClassName.put(SessionFixationProtectionEvent.class,
(r) -> new SessionFixationProtectionEvent(authentication, "old", "new"));
generatorByClassName.put(AuthenticationSwitchUserEvent.class,
(r) -> new AuthenticationSwitchUserEvent(authentication, user));
generatorByClassName.put(HttpSessionCreatedEvent.class,
(r) -> new HttpSessionCreatedEvent(new MockHttpSession()));
}
@ParameterizedTest

View File

@ -32,6 +32,7 @@ import org.springframework.util.Assert;
* instead.
*/
@Deprecated
@SuppressWarnings("serial")
public class AuthenticationCredentialsNotFoundEvent extends AbstractAuthorizationEvent {
private final AuthenticationCredentialsNotFoundException credentialsNotFoundException;

View File

@ -39,6 +39,7 @@ import org.springframework.util.Assert;
* instead
*/
@Deprecated
@SuppressWarnings("serial")
public class AuthorizationFailureEvent extends AbstractAuthorizationEvent {
private final AccessDeniedException accessDeniedException;

View File

@ -34,6 +34,7 @@ import org.springframework.util.Assert;
* instead
*/
@Deprecated
@SuppressWarnings("serial")
public class AuthorizedEvent extends AbstractAuthorizationEvent {
private final Authentication authentication;

View File

@ -34,6 +34,7 @@ import org.springframework.security.authorization.event.AuthorizationGrantedEven
* {@link AuthorizationGrantedEvent#getSource()} to deduce public invocations.
*/
@Deprecated
@SuppressWarnings("serial")
public class PublicInvocationEvent extends AbstractAuthorizationEvent {
/**

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -27,6 +29,9 @@ import org.springframework.security.core.AuthenticationException;
*/
public class AuthenticationFailureBadCredentialsEvent extends AbstractAuthenticationFailureEvent {
@Serial
private static final long serialVersionUID = -5245144711561130379L;
public AuthenticationFailureBadCredentialsEvent(Authentication authentication, AuthenticationException exception) {
super(authentication, exception);
}

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -27,6 +29,9 @@ import org.springframework.security.core.AuthenticationException;
*/
public class AuthenticationFailureCredentialsExpiredEvent extends AbstractAuthenticationFailureEvent {
@Serial
private static final long serialVersionUID = -7595086332769705203L;
public AuthenticationFailureCredentialsExpiredEvent(Authentication authentication,
AuthenticationException exception) {
super(authentication, exception);

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -27,6 +29,9 @@ import org.springframework.security.core.AuthenticationException;
*/
public class AuthenticationFailureDisabledEvent extends AbstractAuthenticationFailureEvent {
@Serial
private static final long serialVersionUID = 8037552364666766279L;
public AuthenticationFailureDisabledEvent(Authentication authentication, AuthenticationException exception) {
super(authentication, exception);
}

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -27,6 +29,9 @@ import org.springframework.security.core.AuthenticationException;
*/
public class AuthenticationFailureExpiredEvent extends AbstractAuthenticationFailureEvent {
@Serial
private static final long serialVersionUID = -8437264795214121718L;
public AuthenticationFailureExpiredEvent(Authentication authentication, AuthenticationException exception) {
super(authentication, exception);
}

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -27,6 +29,9 @@ import org.springframework.security.core.AuthenticationException;
*/
public class AuthenticationFailureLockedEvent extends AbstractAuthenticationFailureEvent {
@Serial
private static final long serialVersionUID = -5126110096093568463L;
public AuthenticationFailureLockedEvent(Authentication authentication, AuthenticationException exception) {
super(authentication, exception);
}

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -27,6 +29,9 @@ import org.springframework.security.core.AuthenticationException;
*/
public class AuthenticationFailureProviderNotFoundEvent extends AbstractAuthenticationFailureEvent {
@Serial
private static final long serialVersionUID = 9122219669183263487L;
public AuthenticationFailureProviderNotFoundEvent(Authentication authentication,
AuthenticationException exception) {
super(authentication, exception);

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -27,6 +29,9 @@ import org.springframework.security.core.AuthenticationException;
*/
public class AuthenticationFailureProxyUntrustedEvent extends AbstractAuthenticationFailureEvent {
@Serial
private static final long serialVersionUID = 1801476426012753252L;
public AuthenticationFailureProxyUntrustedEvent(Authentication authentication, AuthenticationException exception) {
super(authentication, exception);
}

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -27,6 +29,9 @@ import org.springframework.security.core.AuthenticationException;
*/
public class AuthenticationFailureServiceExceptionEvent extends AbstractAuthenticationFailureEvent {
@Serial
private static final long serialVersionUID = 5580062757249390756L;
public AuthenticationFailureServiceExceptionEvent(Authentication authentication,
AuthenticationException exception) {
super(authentication, exception);

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
/**
@ -25,6 +27,9 @@ import org.springframework.security.core.Authentication;
*/
public class AuthenticationSuccessEvent extends AbstractAuthenticationEvent {
@Serial
private static final long serialVersionUID = 2537206344128673963L;
public AuthenticationSuccessEvent(Authentication authentication) {
super(authentication);
}

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
import org.springframework.util.Assert;
@ -34,6 +36,9 @@ import org.springframework.util.Assert;
*/
public class InteractiveAuthenticationSuccessEvent extends AbstractAuthenticationEvent {
@Serial
private static final long serialVersionUID = -1990271553478571709L;
private final Class<?> generatedBy;
public InteractiveAuthenticationSuccessEvent(Authentication authentication, Class<?> generatedBy) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
package org.springframework.security.authentication.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
/**
@ -26,6 +28,9 @@ import org.springframework.security.core.Authentication;
*/
public class LogoutSuccessEvent extends AbstractAuthenticationEvent {
@Serial
private static final long serialVersionUID = 5112491795571632311L;
public LogoutSuccessEvent(Authentication authentication) {
super(authentication);
}

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.jaas.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
/**
@ -26,6 +28,9 @@ import org.springframework.security.core.Authentication;
*/
public class JaasAuthenticationFailedEvent extends JaasAuthenticationEvent {
@Serial
private static final long serialVersionUID = -240510538971925002L;
private final Exception exception;
public JaasAuthenticationFailedEvent(Authentication auth, Exception exception) {

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.jaas.event;
import java.io.Serial;
import org.springframework.security.core.Authentication;
/**
@ -28,6 +30,9 @@ import org.springframework.security.core.Authentication;
*/
public class JaasAuthenticationSuccessEvent extends JaasAuthenticationEvent {
@Serial
private static final long serialVersionUID = 2236826715750256181L;
public JaasAuthenticationSuccessEvent(Authentication auth) {
super(auth);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,6 +30,7 @@ import org.springframework.security.core.Authentication;
* @author Josh Cummings
* @since 5.7
*/
@SuppressWarnings("serial")
public class AuthorizationDeniedEvent<T> extends AuthorizationEvent {
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package org.springframework.security.authorization.event;
import java.io.Serial;
import java.util.function.Supplier;
import org.springframework.context.ApplicationEvent;
@ -31,8 +32,12 @@ import org.springframework.util.Assert;
* @author Josh Cummings
* @since 5.8
*/
@SuppressWarnings("serial")
public class AuthorizationEvent extends ApplicationEvent {
@Serial
private static final long serialVersionUID = -9053927371500241295L;
private final Supplier<Authentication> authentication;
private final AuthorizationResult result;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package org.springframework.security.authorization.event;
import java.io.Serial;
import java.util.function.Supplier;
import org.springframework.context.ApplicationEvent;
@ -30,8 +31,12 @@ import org.springframework.security.core.Authentication;
* @author Josh Cummings
* @since 5.7
*/
@SuppressWarnings("serial")
public class AuthorizationGrantedEvent<T> extends AuthorizationEvent {
@Serial
private static final long serialVersionUID = -8690818228055810339L;
/**
* @deprecated please use a constructor that takes an
* {@link org.springframework.security.authorization.AuthorizationResult}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@ import org.springframework.context.ApplicationEvent;
* @author Josh Cummings
* @since 5.6
*/
@SuppressWarnings("serial")
public class SecurityContextChangedEvent extends ApplicationEvent {
public static final Supplier<SecurityContext> NO_CONTEXT = () -> null;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
package org.springframework.security.core.session;
import java.io.Serial;
import org.springframework.context.ApplicationEvent;
/**
@ -26,6 +28,9 @@ import org.springframework.context.ApplicationEvent;
*/
public class AbstractSessionEvent extends ApplicationEvent {
@Serial
private static final long serialVersionUID = -6878881229287231479L;
public AbstractSessionEvent(Object source) {
super(source);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
package org.springframework.security.web.authentication.session;
import java.io.Serial;
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
import org.springframework.security.core.Authentication;
import org.springframework.util.Assert;
@ -29,6 +31,9 @@ import org.springframework.util.Assert;
*/
public class SessionFixationProtectionEvent extends AbstractAuthenticationEvent {
@Serial
private static final long serialVersionUID = -2554621992006921150L;
private final String oldSessionId;
private final String newSessionId;

View File

@ -16,6 +16,8 @@
package org.springframework.security.web.authentication.switchuser;
import java.io.Serial;
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
@ -27,6 +29,9 @@ import org.springframework.security.core.userdetails.UserDetails;
*/
public class AuthenticationSwitchUserEvent extends AbstractAuthenticationEvent {
@Serial
private static final long serialVersionUID = 6265996480231793939L;
private final UserDetails targetUser;
/**

View File

@ -27,6 +27,7 @@ import org.springframework.security.core.session.SessionCreationEvent;
* @author Ray Krueger
* @author Luke Taylor
*/
@SuppressWarnings("serial")
public class HttpSessionCreatedEvent extends SessionCreationEvent {
public HttpSessionCreatedEvent(HttpSession session) {

View File

@ -33,6 +33,7 @@ import org.springframework.security.core.session.SessionDestroyedEvent;
* @author Luke Taylor
* @author Rob Winch
*/
@SuppressWarnings("serial")
public class HttpSessionDestroyedEvent extends SessionDestroyedEvent {
public HttpSessionDestroyedEvent(HttpSession session) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
package org.springframework.security.web.session;
import java.io.Serial;
import jakarta.servlet.http.HttpSession;
import org.springframework.security.core.session.SessionIdChangedEvent;
@ -26,8 +28,12 @@ import org.springframework.security.core.session.SessionIdChangedEvent;
*
* @since 5.4
*/
@SuppressWarnings("serial")
public class HttpSessionIdChangedEvent extends SessionIdChangedEvent {
@Serial
private static final long serialVersionUID = -5725731666499807941L;
private final String oldSessionId;
private final String newSessionId;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,6 +30,7 @@ import org.springframework.util.Assert;
* @author Rob Winch
* @since 4.2
*/
@SuppressWarnings("serial")
public final class SessionInformationExpiredEvent extends ApplicationEvent {
private final HttpServletRequest request;