فهرست منبع

Add SwitchUserGrantedAuthorityMixIn

Closes gh-11775
Markus Heiden 3 سال پیش
والد
کامیت
5c5503924b

+ 46 - 0
web/src/main/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixIn.java

@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-2022 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.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.web.jackson2;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority;
+
+/**
+ * Jackson mixin class to serialize/deserialize {@link SwitchUserGrantedAuthority}.
+ *
+ * @author Markus Heiden
+ * @since 5.8
+ * @see WebServletJackson2Module
+ * @see org.springframework.security.jackson2.SecurityJackson2Modules
+ */
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
+		isGetterVisibility = JsonAutoDetect.Visibility.NONE)
+public abstract class SwitchUserGrantedAuthorityMixIn {
+
+	@JsonCreator
+	SwitchUserGrantedAuthorityMixIn(@JsonProperty("role") String role, @JsonProperty("source") Authentication source) {
+	}
+
+}

+ 2 - 0
web/src/main/java/org/springframework/security/web/jackson2/WebServletJackson2Module.java

@@ -22,6 +22,7 @@ import jakarta.servlet.http.Cookie;
 
 import org.springframework.security.jackson2.SecurityJackson2Modules;
 import org.springframework.security.web.authentication.WebAuthenticationDetails;
+import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority;
 import org.springframework.security.web.savedrequest.DefaultSavedRequest;
 import org.springframework.security.web.savedrequest.SavedCookie;
 
@@ -56,6 +57,7 @@ public class WebServletJackson2Module extends SimpleModule {
 		context.setMixInAnnotations(SavedCookie.class, SavedCookieMixin.class);
 		context.setMixInAnnotations(DefaultSavedRequest.class, DefaultSavedRequestMixin.class);
 		context.setMixInAnnotations(WebAuthenticationDetails.class, WebAuthenticationDetailsMixin.class);
+		context.setMixInAnnotations(SwitchUserGrantedAuthority.class, SwitchUserGrantedAuthorityMixIn.class);
 	}
 
 }

+ 78 - 0
web/src/test/java/org/springframework/security/web/jackson2/SwitchUserGrantedAuthorityMixInTest.java

@@ -0,0 +1,78 @@
+/*
+ * Copyright 2002-2022 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.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.web.jackson2;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+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.SimpleGrantedAuthorityMixinTests;
+import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Markus Heiden
+ * @since 5.8
+ */
+public class SwitchUserGrantedAuthorityMixInTest extends AbstractMixinTests {
+
+	// language=JSON
+	private static final String SWITCH_JSON = """
+			{
+				"@class": "org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority",
+				"role": "switched",
+				"source": {
+					"@class": "org.springframework.security.authentication.UsernamePasswordAuthenticationToken",
+					"principal": "principal",
+					"credentials": "credentials",
+					"authenticated": true,
+					"details": null,
+					"authorities": %s
+				}
+			}
+			""".formatted(SimpleGrantedAuthorityMixinTests.AUTHORITIES_ARRAYLIST_JSON);
+	SwitchUserGrantedAuthority expected;
+
+	Authentication source;
+
+	@BeforeEach
+	public void setupExpected() {
+		this.source = new UsernamePasswordAuthenticationToken("principal", "credentials",
+				AuthorityUtils.createAuthorityList("ROLE_USER"));
+		this.expected = new SwitchUserGrantedAuthority("switched", this.source);
+	}
+
+	@Test
+	public void serializeWhenPrincipalCredentialsAuthoritiesThenSuccess() throws Exception {
+		String serializedJson = this.mapper.writeValueAsString(this.expected);
+		JSONAssert.assertEquals(SWITCH_JSON, serializedJson, true);
+	}
+
+	@Test
+	public void deserializeAuthenticatedUsernamePasswordAuthenticationTokenMixinTest() throws Exception {
+		SwitchUserGrantedAuthority deserialized = this.mapper.readValue(SWITCH_JSON, SwitchUserGrantedAuthority.class);
+		assertThat(deserialized).isNotNull();
+		assertThat(deserialized.getAuthority()).isEqualTo("switched");
+		assertThat(deserialized.getSource()).isEqualTo(this.source);
+	}
+
+}