From fe2f8a1e2d603af03414a4415c5099491198f702 Mon Sep 17 00:00:00 2001 From: John Niang Date: Thu, 8 May 2025 11:44:47 +0800 Subject: [PATCH] Add SwitchUserGrantedAuthority to Web Jackson Module Closes gh-17041 Signed-off-by: John Niang --- .../SwitchUserGrantedAuthorityMixIn.java | 3 +- .../web/jackson2/WebJackson2Module.java | 13 ++++-- .../SwitchUserGrantedAuthorityMixInTests.java | 46 +++++++++++++++---- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/web/src/main/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixIn.java b/web/src/main/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixIn.java index 4fff7ffdc41..f61b8a05bf0 100644 --- a/web/src/main/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixIn.java +++ b/web/src/main/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixIn.java @@ -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 @@ * * @author Markus Heiden * @since 6.3 + * @see WebJackson2Module * @see WebServletJackson2Module * @see org.springframework.security.jackson2.SecurityJackson2Modules */ diff --git a/web/src/main/java/org/springframework/security/web/jackson2/WebJackson2Module.java b/web/src/main/java/org/springframework/security/web/jackson2/WebJackson2Module.java index 87daedcc40d..b8cee4fee05 100644 --- a/web/src/main/java/org/springframework/security/web/jackson2/WebJackson2Module.java +++ b/web/src/main/java/org/springframework/security/web/jackson2/WebJackson2Module.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 the original author or authors. + * Copyright 2015-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. @@ -21,14 +21,16 @@ import org.springframework.security.jackson2.SecurityJackson2Modules; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; +import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority; import org.springframework.security.web.csrf.DefaultCsrfToken; /** * Jackson module for spring-security-web. This module register - * {@link DefaultCsrfTokenMixin} and {@link PreAuthenticatedAuthenticationTokenMixin}. If - * no default typing enabled by default then it'll enable it because typing info is needed - * to properly serialize/deserialize objects. In order to use this module just add this - * module into your ObjectMapper configuration. + * {@link DefaultCsrfTokenMixin}, {@link PreAuthenticatedAuthenticationTokenMixin} and + * {@link SwitchUserGrantedAuthorityMixIn}. If no default typing enabled by default then + * it'll enable it because typing info is needed to properly serialize/deserialize + * objects. In order to use this module just add this module into your ObjectMapper + * configuration. * *
  *     ObjectMapper mapper = new ObjectMapper();
@@ -53,6 +55,7 @@ public void setupModule(SetupContext context) {
 		context.setMixInAnnotations(DefaultCsrfToken.class, DefaultCsrfTokenMixin.class);
 		context.setMixInAnnotations(PreAuthenticatedAuthenticationToken.class,
 				PreAuthenticatedAuthenticationTokenMixin.class);
+		context.setMixInAnnotations(SwitchUserGrantedAuthority.class, SwitchUserGrantedAuthorityMixIn.class);
 	}
 
 }
diff --git a/web/src/test/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixInTests.java b/web/src/test/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixInTests.java
index 703811658c6..70bba02513f 100644
--- a/web/src/test/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixInTests.java
+++ b/web/src/test/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixInTests.java
@@ -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.
@@ -16,14 +16,20 @@
 
 package org.springframework.security.web.jackson2;
 
+import java.util.stream.Stream;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.skyscreamer.jsonassert.JSONAssert;
 
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.jackson2.AbstractMixinTests;
+import org.springframework.security.jackson2.CoreJackson2Module;
+import org.springframework.security.jackson2.SecurityJackson2Modules;
 import org.springframework.security.jackson2.SimpleGrantedAuthorityMixinTests;
 import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority;
 
@@ -33,7 +39,7 @@
  * @author Markus Heiden
  * @since 6.3
  */
-public class SwitchUserGrantedAuthorityMixInTests extends AbstractMixinTests {
+public class SwitchUserGrantedAuthorityMixInTests {
 
 	// language=JSON
 	private static final String SWITCH_JSON = """
@@ -53,22 +59,42 @@ public class SwitchUserGrantedAuthorityMixInTests extends AbstractMixinTests {
 
 	private Authentication source;
 
+	static Stream mappers() {
+		ObjectMapper securityJackson2ModulesMapper = new ObjectMapper();
+		ClassLoader classLoader = SwitchUserGrantedAuthorityMixInTests.class.getClassLoader();
+		securityJackson2ModulesMapper.registerModules(SecurityJackson2Modules.getModules(classLoader));
+
+		ObjectMapper webJackson2ModuleMapper = new ObjectMapper();
+		webJackson2ModuleMapper.registerModule(new CoreJackson2Module());
+		webJackson2ModuleMapper.registerModule(new WebJackson2Module());
+
+		ObjectMapper webServletJackson2ModuleMapper = new ObjectMapper();
+		webServletJackson2ModuleMapper.registerModule(new CoreJackson2Module());
+		webServletJackson2ModuleMapper.registerModule(new WebServletJackson2Module());
+
+		return Stream.of(Arguments.of(securityJackson2ModulesMapper), Arguments.of(webJackson2ModuleMapper),
+				Arguments.of(webServletJackson2ModuleMapper));
+	}
+
 	@BeforeEach
 	public void setUp() {
 		this.source = new UsernamePasswordAuthenticationToken("principal", "credentials",
 				AuthorityUtils.createAuthorityList("ROLE_USER"));
 	}
 
-	@Test
-	public void serializeWhenPrincipalCredentialsAuthoritiesThenSuccess() throws Exception {
+	@ParameterizedTest
+	@MethodSource("mappers")
+	public void serializeWhenPrincipalCredentialsAuthoritiesThenSuccess(ObjectMapper mapper) throws Exception {
 		SwitchUserGrantedAuthority expected = new SwitchUserGrantedAuthority("switched", this.source);
-		String serializedJson = this.mapper.writeValueAsString(expected);
+		String serializedJson = mapper.writeValueAsString(expected);
 		JSONAssert.assertEquals(SWITCH_JSON, serializedJson, true);
 	}
 
-	@Test
-	public void deserializeWhenSourceIsUsernamePasswordAuthenticationTokenThenSuccess() throws Exception {
-		SwitchUserGrantedAuthority deserialized = this.mapper.readValue(SWITCH_JSON, SwitchUserGrantedAuthority.class);
+	@ParameterizedTest
+	@MethodSource("mappers")
+	public void deserializeWhenSourceIsUsernamePasswordAuthenticationTokenThenSuccess(ObjectMapper mapper)
+			throws Exception {
+		SwitchUserGrantedAuthority deserialized = mapper.readValue(SWITCH_JSON, SwitchUserGrantedAuthority.class);
 		assertThat(deserialized).isNotNull();
 		assertThat(deserialized.getAuthority()).isEqualTo("switched");
 		assertThat(deserialized.getSource()).isEqualTo(this.source);