Skip to content

Commit ad0485f

Browse files
committed
Add SwitchUserGrantedAuthority to WebFlux Jackson Module
Closes gh-17041 Signed-off-by: John Niang <johnniang@foxmail.com>
1 parent ff8b77d commit ad0485f

File tree

3 files changed

+47
-19
lines changed

3 files changed

+47
-19
lines changed

web/src/main/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixIn.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
3030
*
3131
* @author Markus Heiden
3232
* @since 6.3
33+
* @see WebJackson2Module
3334
* @see WebServletJackson2Module
3435
* @see org.springframework.security.jackson2.SecurityJackson2Modules
3536
*/

web/src/main/java/org/springframework/security/web/jackson2/WebJackson2Module.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2016 the original author or authors.
2+
* Copyright 2015-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,14 +21,16 @@
2121

2222
import org.springframework.security.jackson2.SecurityJackson2Modules;
2323
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
24+
import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority;
2425
import org.springframework.security.web.csrf.DefaultCsrfToken;
2526

2627
/**
2728
* Jackson module for spring-security-web. This module register
28-
* {@link DefaultCsrfTokenMixin} and {@link PreAuthenticatedAuthenticationTokenMixin}. If
29-
* no default typing enabled by default then it'll enable it because typing info is needed
30-
* to properly serialize/deserialize objects. In order to use this module just add this
31-
* module into your ObjectMapper configuration.
29+
* {@link DefaultCsrfTokenMixin}, {@link PreAuthenticatedAuthenticationTokenMixin} and
30+
* {@link SwitchUserGrantedAuthorityMixIn}. If no default typing enabled by default then
31+
* it'll enable it because typing info is needed to properly serialize/deserialize
32+
* objects. In order to use this module just add this module into your ObjectMapper
33+
* configuration.
3234
*
3335
* <pre>
3436
* ObjectMapper mapper = new ObjectMapper();
@@ -53,6 +55,7 @@ public void setupModule(SetupContext context) {
5355
context.setMixInAnnotations(DefaultCsrfToken.class, DefaultCsrfTokenMixin.class);
5456
context.setMixInAnnotations(PreAuthenticatedAuthenticationToken.class,
5557
PreAuthenticatedAuthenticationTokenMixin.class);
58+
context.setMixInAnnotations(SwitchUserGrantedAuthority.class, SwitchUserGrantedAuthorityMixIn.class);
5659
}
5760

5861
}

web/src/test/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixInTests.java

+37-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,24 +16,28 @@
1616

1717
package org.springframework.security.web.jackson2;
1818

19+
import static org.assertj.core.api.Assertions.assertThat;
20+
21+
import com.fasterxml.jackson.databind.ObjectMapper;
22+
import java.util.stream.Stream;
1923
import org.junit.jupiter.api.BeforeEach;
20-
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.params.ParameterizedTest;
25+
import org.junit.jupiter.params.provider.Arguments;
26+
import org.junit.jupiter.params.provider.MethodSource;
2127
import org.skyscreamer.jsonassert.JSONAssert;
22-
2328
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
2429
import org.springframework.security.core.Authentication;
2530
import org.springframework.security.core.authority.AuthorityUtils;
26-
import org.springframework.security.jackson2.AbstractMixinTests;
31+
import org.springframework.security.jackson2.CoreJackson2Module;
32+
import org.springframework.security.jackson2.SecurityJackson2Modules;
2733
import org.springframework.security.jackson2.SimpleGrantedAuthorityMixinTests;
2834
import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority;
2935

30-
import static org.assertj.core.api.Assertions.assertThat;
31-
3236
/**
3337
* @author Markus Heiden
3438
* @since 6.3
3539
*/
36-
public class SwitchUserGrantedAuthorityMixInTests extends AbstractMixinTests {
40+
public class SwitchUserGrantedAuthorityMixInTests {
3741

3842
// language=JSON
3943
private static final String SWITCH_JSON = """
@@ -53,22 +57,42 @@ public class SwitchUserGrantedAuthorityMixInTests extends AbstractMixinTests {
5357

5458
private Authentication source;
5559

60+
static Stream<Arguments> mappers() {
61+
ObjectMapper securityJackson2ModulesMapper = new ObjectMapper();
62+
ClassLoader classLoader = SwitchUserGrantedAuthorityMixInTests.class.getClassLoader();
63+
securityJackson2ModulesMapper.registerModules(SecurityJackson2Modules.getModules(classLoader));
64+
65+
ObjectMapper webJackson2ModuleMapper = new ObjectMapper();
66+
webJackson2ModuleMapper.registerModule(new CoreJackson2Module());
67+
webJackson2ModuleMapper.registerModule(new WebJackson2Module());
68+
69+
ObjectMapper webServletJackson2ModuleMapper = new ObjectMapper();
70+
webServletJackson2ModuleMapper.registerModule(new CoreJackson2Module());
71+
webServletJackson2ModuleMapper.registerModule(new WebServletJackson2Module());
72+
73+
return Stream.of(Arguments.of(securityJackson2ModulesMapper), Arguments.of(webJackson2ModuleMapper),
74+
Arguments.of(webServletJackson2ModuleMapper));
75+
}
76+
5677
@BeforeEach
5778
public void setUp() {
5879
this.source = new UsernamePasswordAuthenticationToken("principal", "credentials",
5980
AuthorityUtils.createAuthorityList("ROLE_USER"));
6081
}
6182

62-
@Test
63-
public void serializeWhenPrincipalCredentialsAuthoritiesThenSuccess() throws Exception {
83+
@ParameterizedTest
84+
@MethodSource("mappers")
85+
public void serializeWhenPrincipalCredentialsAuthoritiesThenSuccess(ObjectMapper mapper) throws Exception {
6486
SwitchUserGrantedAuthority expected = new SwitchUserGrantedAuthority("switched", this.source);
65-
String serializedJson = this.mapper.writeValueAsString(expected);
87+
String serializedJson = mapper.writeValueAsString(expected);
6688
JSONAssert.assertEquals(SWITCH_JSON, serializedJson, true);
6789
}
6890

69-
@Test
70-
public void deserializeWhenSourceIsUsernamePasswordAuthenticationTokenThenSuccess() throws Exception {
71-
SwitchUserGrantedAuthority deserialized = this.mapper.readValue(SWITCH_JSON, SwitchUserGrantedAuthority.class);
91+
@ParameterizedTest
92+
@MethodSource("mappers")
93+
public void deserializeWhenSourceIsUsernamePasswordAuthenticationTokenThenSuccess(ObjectMapper mapper)
94+
throws Exception {
95+
SwitchUserGrantedAuthority deserialized = mapper.readValue(SWITCH_JSON, SwitchUserGrantedAuthority.class);
7296
assertThat(deserialized).isNotNull();
7397
assertThat(deserialized.getAuthority()).isEqualTo("switched");
7498
assertThat(deserialized.getSource()).isEqualTo(this.source);

0 commit comments

Comments
 (0)