From 39fdceab594e14897cef58dbf3feb790f1f56636 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Mon, 5 May 2025 13:36:21 -0600 Subject: [PATCH] Add Missing Serializable Samples Issue gh-17038 --- ...gSecurityCoreVersionSerializableTests.java | 80 ++++++++++++------ ...s.CycleInRoleHierarchyException.serialized | Bin 0 -> 10740 bytes ...zation.event.AuthorizationEvent.serialized | Bin 0 -> 1603 bytes ...event.AuthorizationGrantedEvent.serialized | Bin 0 -> 1692 bytes ...nnotation.AlreadyBuiltException.serialized | Bin 0 -> 10715 bytes ...ssion.HttpSessionIdChangedEvent.serialized | Bin 0 -> 421 bytes ...ropertiesOutput$ExtensionOutput.serialized | Bin 0 -> 115 bytes 7 files changed, 55 insertions(+), 25 deletions(-) create mode 100644 config/src/test/resources/serialized/6.4.x/org.springframework.security.access.hierarchicalroles.CycleInRoleHierarchyException.serialized create mode 100644 config/src/test/resources/serialized/6.4.x/org.springframework.security.authorization.event.AuthorizationEvent.serialized create mode 100644 config/src/test/resources/serialized/6.4.x/org.springframework.security.authorization.event.AuthorizationGrantedEvent.serialized create mode 100644 config/src/test/resources/serialized/6.4.x/org.springframework.security.config.annotation.AlreadyBuiltException.serialized create mode 100644 config/src/test/resources/serialized/6.4.x/org.springframework.security.web.session.HttpSessionIdChangedEvent.serialized create mode 100644 config/src/test/resources/serialized/6.4.x/org.springframework.security.web.webauthn.api.CredentialPropertiesOutput$ExtensionOutput.serialized diff --git a/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java b/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java index e053a6f730..c9843c7ed6 100644 --- a/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java +++ b/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java @@ -16,8 +16,6 @@ package org.springframework.security; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -38,7 +36,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -48,7 +45,6 @@ import java.util.function.Supplier; import java.util.stream.Stream; import jakarta.servlet.http.Cookie; -import org.apache.commons.lang3.ObjectUtils; import org.apereo.cas.client.validation.AssertionImpl; import org.instancio.Instancio; import org.instancio.InstancioApi; @@ -139,14 +135,11 @@ import org.springframework.security.oauth2.client.authentication.OAuth2Authoriza import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken; import org.springframework.security.oauth2.client.authentication.TestOAuth2AuthenticationTokens; import org.springframework.security.oauth2.client.authentication.TestOAuth2AuthorizationCodeAuthenticationTokens; -import org.springframework.security.oauth2.client.event.OAuth2AuthorizedClientRefreshedEvent; -import org.springframework.security.oauth2.client.oidc.authentication.event.OidcUserRefreshedEvent; import org.springframework.security.oauth2.client.oidc.authentication.logout.OidcLogoutToken; import org.springframework.security.oauth2.client.oidc.authentication.logout.TestOidcLogoutTokens; import org.springframework.security.oauth2.client.oidc.session.OidcSessionInformation; import org.springframework.security.oauth2.client.oidc.session.TestOidcSessionInformations; import org.springframework.security.oauth2.client.registration.ClientRegistration; -import org.springframework.security.oauth2.client.registration.ClientRegistration.ClientSettings; import org.springframework.security.oauth2.client.registration.TestClientRegistrations; import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrincipal; import org.springframework.security.oauth2.core.OAuth2AccessToken; @@ -162,7 +155,6 @@ import org.springframework.security.oauth2.core.TestOAuth2AuthenticatedPrincipal import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse; -import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses; import org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationExchanges; import org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationRequests; import org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationResponses; @@ -187,7 +179,6 @@ import org.springframework.security.oauth2.server.resource.BearerTokenErrors; import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException; import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; -import org.springframework.security.oauth2.server.resource.authentication.DPoPAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.security.oauth2.server.resource.introspection.BadOpaqueTokenException; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal; @@ -253,9 +244,7 @@ import org.springframework.security.web.webauthn.api.TestAuthenticationAssertion import org.springframework.security.web.webauthn.api.TestBytes; import org.springframework.security.web.webauthn.api.TestPublicKeyCredential; import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialRequestOptions; -import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialUserEntities; import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialUserEntity; -import org.springframework.security.web.webauthn.api.TestPublicKeyCredentials; import org.springframework.security.web.webauthn.api.UserVerificationRequirement; import org.springframework.security.web.webauthn.authentication.WebAuthnAuthentication; import org.springframework.security.web.webauthn.authentication.WebAuthnAuthenticationRequestToken; @@ -417,6 +406,9 @@ class SpringSecurityCoreVersionSerializableTests { generatorByClassName.put(OAuth2IntrospectionException.class, (r) -> new OAuth2IntrospectionException("message", new RuntimeException())); + // config + generatorByClassName.put(AlreadyBuiltException.class, (r) -> new AlreadyBuiltException("message")); + // core generatorByClassName.put(RunAsUserToken.class, (r) -> { RunAsUserToken token = new RunAsUserToken("key", user, "creds", user.getAuthorities(), @@ -508,6 +500,20 @@ class SpringSecurityCoreVersionSerializableTests { generatorByClassName.put(AuthorizationDecision.class, (r) -> new AuthorizationDecision(true)); generatorByClassName.put(AuthorityAuthorizationDecision.class, (r) -> new AuthorityAuthorizationDecision(true, AuthorityUtils.createAuthorityList("ROLE_USER"))); + generatorByClassName.put(CycleInRoleHierarchyException.class, (r) -> new CycleInRoleHierarchyException()); + generatorByClassName.put(AuthorizationEvent.class, + (r) -> new AuthorizationEvent(new SerializableSupplier<>(authentication), "source", + new AuthorizationDecision(true))); + generatorByClassName.put(AuthorizationGrantedEvent.class, + (r) -> new AuthorizationGrantedEvent<>(new SerializableSupplier<>(authentication), "source", + new AuthorizationDecision(true))); + instancioByClassName.put(AuthorizationGrantedEvent.class, () -> { + InstancioOfClassApi instancio = Instancio.of(AuthorizationGrantedEvent.class); + instancio.withTypeParameters(String.class); + instancio.supply(Select.all(AuthorizationGrantedEvent.class), + generatorByClassName.get(AuthorizationGrantedEvent.class)); + return instancio; + }); // cas generatorByClassName.put(CasServiceTicketAuthenticationToken.class, (r) -> { @@ -561,6 +567,7 @@ class SpringSecurityCoreVersionSerializableTests { token.setDetails(details); return token; }); + generatorByClassName.put(Saml2LogoutRequest.class, (r) -> TestSaml2LogoutRequests.create()); // web generatorByClassName.put(AnonymousAuthenticationToken.class, (r) -> { @@ -616,20 +623,8 @@ class SpringSecurityCoreVersionSerializableTests { request.addPreferredLocale(Locale.ENGLISH); return new SimpleSavedRequest(new DefaultSavedRequest(request, new PortResolverImpl(), "continue")); }); - - // webauthn - generatorByClassName.put(Bytes.class, (r) -> TestBytes.get()); - generatorByClassName.put(ImmutablePublicKeyCredentialUserEntity.class, - (r) -> TestPublicKeyCredentialUserEntity.userEntity().id(TestBytes.get()).build()); - generatorByClassName.put(WebAuthnAuthentication.class, (r) -> { - PublicKeyCredentialUserEntity userEntity = TestPublicKeyCredentialUserEntity.userEntity() - .id(TestBytes.get()) - .build(); - List authorities = AuthorityUtils.createAuthorityList("ROLE_USER"); - WebAuthnAuthentication webAuthnAuthentication = new WebAuthnAuthentication(userEntity, authorities); - webAuthnAuthentication.setDetails(details); - return webAuthnAuthentication; - }); + generatorByClassName.put(HttpSessionIdChangedEvent.class, + (r) -> new HttpSessionIdChangedEvent(new MockHttpSession(), "1")); // webauthn CredProtectAuthenticationExtensionsClientInput.CredProtect credProtect = new CredProtectAuthenticationExtensionsClientInput.CredProtect( @@ -686,6 +681,25 @@ class SpringSecurityCoreVersionSerializableTests { generatorByClassName.put(WebAuthnAuthenticationRequestToken.class, (r) -> requestToken); generatorByClassName.put(AuthenticatorAttachment.class, (r) -> AuthenticatorAttachment.PLATFORM); // @formatter:on + generatorByClassName.put(ImmutablePublicKeyCredentialUserEntity.class, + (r) -> TestPublicKeyCredentialUserEntity.userEntity().id(TestBytes.get()).build()); + generatorByClassName.put(WebAuthnAuthentication.class, (r) -> { + PublicKeyCredentialUserEntity userEntity = TestPublicKeyCredentialUserEntity.userEntity() + .id(TestBytes.get()) + .build(); + List authorities = AuthorityUtils.createAuthorityList("ROLE_USER"); + WebAuthnAuthentication webAuthnAuthentication = new WebAuthnAuthentication(userEntity, authorities); + webAuthnAuthentication.setDetails(details); + return webAuthnAuthentication; + }); + // @formatter:on + generatorByClassName.put(CredentialPropertiesOutput.ExtensionOutput.class, + (r) -> new CredentialPropertiesOutput(true).getOutput()); + + // One-Time Token + DefaultOneTimeToken oneTimeToken = new DefaultOneTimeToken(UUID.randomUUID().toString(), "user", + Instant.now().plusSeconds(300)); + generatorByClassName.put(DefaultOneTimeToken.class, (t) -> oneTimeToken); } @ParameterizedTest @@ -862,4 +876,20 @@ class SpringSecurityCoreVersionSerializableTests { return String.join(".", parts); } + @SuppressWarnings("serial") + private static final class SerializableSupplier implements Supplier, Serializable { + + private final T value; + + SerializableSupplier(T value) { + this.value = value; + } + + @Override + public T get() { + return this.value; + } + + } + } diff --git a/config/src/test/resources/serialized/6.4.x/org.springframework.security.access.hierarchicalroles.CycleInRoleHierarchyException.serialized b/config/src/test/resources/serialized/6.4.x/org.springframework.security.access.hierarchicalroles.CycleInRoleHierarchyException.serialized new file mode 100644 index 0000000000000000000000000000000000000000..43d7d327459fd83c9d89098ee53f0a9643b66db0 GIT binary patch literal 10740 zcmeHNU2Gjk6`t!Pj$`sqQs=jE(oIr`x^dz(KXux~wVlMN;{;zPkhT=9_l~dE-n+Zm zo$L6979`q&Kva|>`cR>YAE62f1gM1u^_5geeSwEQ@Bl)ns1g#qAn||{!Z|auv$H?< z`kIC(;)n6<%$ak}eCN!WIWzaie!IKb{aOir?Pe_1Lz79ly>|OwNSd zp1i&11VR@OLVf_&-kw058(^)v_1eCpe|WKjbUjWwr~R;Iu~E|PIvyRb*QRJVM%LM` z6-8sdRiWWHI1A2b#TZ#zq0oWo4Pn1*?V5I6s!?^}t@E96@c@GIAUhbUdK(Y{!QhqoHTHW|exdh?pOmH7Byov+?IJ zwSC^sNKd{|O74=QsV?!nl=xT^i8Gd0aREv5azw*2c&Y2qiV|@t^l@$bAtMj8CXhO8 zgaxBUPtd6DGF_XaQk#?il{V*uu8iz1)J1knO;&*>c?F)A3hZm5fYSYpWrG7VvMJNT zxg(RU`n;axY_ZsdMK2>8s={`3+^^6pmRr}Y((y8U4h-odyGE zv=+F4maHjzAJW;pr4Z@I+7U)Ng;b5G<2^;R4r}XSpMW*SBMcp?haqeYGVt(-NTYZ# zxdVR?#vYoj%q6iQq|+`~E)EK`a)F1+LB9L?;b9oi>3H-0obogX>f``4A1dTCOkG-q z80A&djKutRx9V1)3^1~a?-o-Q?x>xIj+uRCzle7rz2i7Y-;!)6@f3tWMm{Dg2|L8; z6c(pd%DW}C*f%3*V)K| zY=C)Zo8-J#@m&qo)n$E)%fjLk7N3F*P0`_=i+gY0GSB2jZBLDwq_AiqxaCJy`A9~d zYzt{HH9wwu)e&xK)CSR%0DIJ^fL2MLt&m0Bb~Q(EWif)^a{@;A zIj0ca3XSa0!KG}X+Y86V+OXYNF2Ty@L`9`VBN)a2?=7UJTuW*{dnggd};fsl?x}smpkmIMP6AUj#5J$3s zB~BF&X{ghr70tofP5+eB+b*G&vz)-}A#&!a+b~imd;vD<>0(jK&EXX_2ZpseBQ02` z?D$nak`ZltYRir|8`!7upPWpm75a5AwIhiWDN1NVtrNOY7M<}oax>nTM^Wck$qc~H zlpj362^jgz63twObQBzzT9x=d0xv7j@FHmYA*6uw4yN>G+q5yJQGKfBr1rWGrJ7fk zsHX0I#xR|>Ad4Dqcvj7^bzPBrJ%`QjxKJ#(zvKyC;slKFjIf>96mPC5TaQk=_==G` zZ@QCXl2eT@27XrmI`+MkB+JqtjQ-dS@aXzB93Btw!y`Z5MGOpAGtcN;JHv*jTB6u0csUhtm)6gf$o>|v-= zGF(W&X$$W}U{hDk(!A>-3qWs}pf%X-;qZkJWNgv#FA%an5hDF4XHerD#08EsBP%7} z0(PZMZJPGjT`_H2_HT!1*`LxdXuw7SZmk9OKqU;@sF zt#2rzqLmM;4Ew)}#rLpiVnyr{Kx6IaSY(z`Nw)^}zga*82Ef)|V8NqNAy7+36WRT$ zKpfzRt?yv*(Qtwt0hufkYwsG-J+qK|?n@STUreO3CnxmN)QR{2wrEGI9D&G;uvwh% zu{Ix{wot^P$M|gGf*cw;2a%s(^XIX67K`U}f|s#{E1Br*Lev#+i2P8g4iw0V2gh8PMQ}c$G=C9mUxsu_B(j69tBdC`HZ#NjPm~d+KQ9eb zr2gO@n)!@Pq`L@@@II`4MF;8xw!pI@fA`E>k+-_xX_f`U%~P{3mG-2<&rzws$PzQ% zoD})owY|8bSophAxOUm5?nPXy?%6YNfe-Je)D*92BG-q@?2GVg1;}Y-a?#tOw^;Cx zxL_>qKv5!COTi*8bXyQSf_*$*2oCv-ICViRQul-(iLJ`RIf<9sI#g zJ&qglf)q9b)k&lHN{JC;k?~wx$dC9#Q52=w#OoXuBMjC6}1-WYv-%1Myu z8JH#i!OmTtrIflnVt$}2bqeJ1JN?DwmFtkpD~J?+jO=LA6Wg)W6HDxXr_q0d#NxNn zad-@ym#;wa!>D-A+}W&4g1=Ji=Y8mjnXHFg;IQvN0Cr;kKoQXaBqEPu@mMn=cn`&{ z$FUeHBtiokFg^a*DFJojUx!qjD6p74qrG$v%O<#)hs+Ug=^?JgjdE&T@wga66tacS z33rx~fyG|Eb2n&kOj{^<4Tj*wlP-vLAb#o-3x)T`=AFu(DREDOxbc?az*QC+v4p{j z6~L8{5r4yaP2Qf=?+LaRjfv$a?>+Hb`$l{thXuIMIBXhx=uwVP53IAKOa7Dx0sIXp zeL_>ZMKHmi%fS|ej{j+1HTvNyBl(neS{Bw-Tt*2mWUR0h324&8u&(6ADqNXdfD1DC zS(_*BzwrlFy2Yz}vJdlNP$U}!Dsrk-CqD7>t7Pe|fFb`mpz;|xd-!3XTQLW@gQ^`^ zz`@A2!ggh?6f8GD;1e3~tp%1F5u>$1{9TiHsOOdgEr#TPNRm{g03zEd&ey0VmWb^8f$< literal 0 HcmV?d00001 diff --git a/config/src/test/resources/serialized/6.4.x/org.springframework.security.authorization.event.AuthorizationEvent.serialized b/config/src/test/resources/serialized/6.4.x/org.springframework.security.authorization.event.AuthorizationEvent.serialized new file mode 100644 index 0000000000000000000000000000000000000000..568c4a3ac20bce16fcb82e8b004f27231125c6e3 GIT binary patch literal 1603 zcmb7EJ7^S96urCIWV3{PHKIbS60wjOv@}gVu8T4xA+syGis9|-%leY}<;|O95=o3A z_yHp*iXs+TiP~yuYatez+9I{4v9VF`zS&)7Him>uG4L+;bM86ky?2|?>~R=%ct!DC z&g{xGCl+0B_^jel!{xIG2Q^1|6~n zgUkqv1oUY$WS*$LV5U0l+lFkV>b~omjPgMZS~&H5QwSK+5R1A6i(1E`HegX3P)vp$ z1_KVqw_C?>Y(WD=E@xI@g}6(%eoWoTec4Dt;v8fIv#2MCG(!!c z-Or32w3c5d0Rk5w@#N*N%q!&Z@^(Y(xD`DlSFcfueADxkdq{##IU^>LTQX@LM|=J8 zNS&el(%}zp*V->2NDZ3jiRn`TJylLkVpr5Ew!y$fB;z|GX;eljc$C{H`2_Jil)Wq| zjfBfPv($$0OPZmwZ3d@hnLtc$4ptzoK}POoFqfEN0GZ3}1;KF16Py@go5|~Mj;+|a zaz_%HiqIZIPRkm!$us&=Fr*C*#0)m-m?kQP?4q;MWhw}(feqXQ5_B{YHcIvS3%2Ey z*))?h=FkYNe!lYiNZ2%CNXFVi)%HbQ zhB+sTvU_mjTi>%!tmj%(Sef}WiWB<>zpy6xod5PbAlO@+{J(a3ZWx`|;p zzAeTaI~%wR-BpCHD5g2atPJ(Wd>2nmQ(NlwpC3A7Lg`eX5nA1v#U=Lrc$ToF^}{nd z13%nnAkraHtBOVQo3}4D$+rSC&g`A5 zet9iIp++6cC7cL{NBm*isuv`N-atUdHQRCA<@%}uQgTZiJ+$NK+EuDO@wJiF(`jlj X`B1H&+OS&5T|na&Azi7u2wD3Fm7qFw literal 0 HcmV?d00001 diff --git a/config/src/test/resources/serialized/6.4.x/org.springframework.security.authorization.event.AuthorizationGrantedEvent.serialized b/config/src/test/resources/serialized/6.4.x/org.springframework.security.authorization.event.AuthorizationGrantedEvent.serialized new file mode 100644 index 0000000000000000000000000000000000000000..6d3ca9608f9cacaa523776a846715debb31b4d0c GIT binary patch literal 1692 zcmbtVO-vI}5T2GIG{~Q%L{0Dn#)H{LkCGUEtc_#?gtkV}Kwh^Ge6ZbJ-oAx`0nwPC zCSsz|Xp9GMMvXT;di7vDC}&JKD;FrJS2B@Ebd zQga3VL+J65ldpygX#QYRGuicq4v=ZXD36gQN9H#&GQzxaZfa{xk*p8trxL2)i`*R+gV zOZlp$N?IY`{5+Q~l91w3FcVeFnmmoI-OkELnW6N;;difA8!sS89cpKp>2U=IikzCv znv55*br&2&GPEO-YGt&H%cX^08fLDGe##N0fpBSinp@yMVbfQ(!H_&h3Cwh7UAd#x*pijZHHD#O6dEg#^PCP1bVkD~fwVz;g~9r5 z(?q3^U36Amjw>cgU<*zN2|5}G8>G6O87pt+#DpLzbm6LB&0QzneqU|zNspKqQP5J+ zhH`wn?OrZubEprNKaTx8;uj4W#MpjcwYH#2uas<_su!+*>3H&iJ*$DxIf%Gofs^GR zG#8;?oTP6@q7AfJc`e|ANQt~-^3oO{wu!v?KwY#}MB3&SXQdSF8+4X}=*WGh8vnk$4#afL>xcS;r~>@hqOEV90TMrYuI^K=C|1gce=1M4k!-2Z&<>2ij)0NroF zo2|jkwB#JK)*lZ)c(}Q8sfKn1W}MwSSDk-_>bLU_lT6t%;1A0dy+9b+3ksU9TDI*h vmPb_(p((L-&yKB2f2Gp5qtvo^I>QY?i)!uEM!ufi1~l#{)J+z@CCJ(zGiF^1 literal 0 HcmV?d00001 diff --git a/config/src/test/resources/serialized/6.4.x/org.springframework.security.config.annotation.AlreadyBuiltException.serialized b/config/src/test/resources/serialized/6.4.x/org.springframework.security.config.annotation.AlreadyBuiltException.serialized new file mode 100644 index 0000000000000000000000000000000000000000..d3344aeda54a287d2730736f895487bb3cf89a2f GIT binary patch literal 10715 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 L7?_H(D+(9^Dt9X> literal 0 HcmV?d00001