Browse Source

RequestAttributeSecurityContextRepository never null SecurityContext

Previously loadContext(HttpServletRequest) could return a Supplier that
returned a null SecurityContext

This commit ensures that null is never returned by the Supplier by
returning SecurityContextHolder.createEmptyContext() instead.

Closes gh-11606
Rob Winch 3 years ago
parent
commit
c23324e7a7

+ 12 - 4
web/src/main/java/org/springframework/security/web/context/RequestAttributeSecurityContextRepository.java

@@ -66,18 +66,26 @@ public final class RequestAttributeSecurityContextRepository implements Security
 
 	@Override
 	public boolean containsContext(HttpServletRequest request) {
-		return loadContext(request).get() != null;
+		return getContext(request) != null;
 	}
 
 	@Override
 	public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {
-		SecurityContext context = loadContext(requestResponseHolder.getRequest()).get();
-		return (context != null) ? context : SecurityContextHolder.createEmptyContext();
+		return getContextOrEmpty(requestResponseHolder.getRequest());
 	}
 
 	@Override
 	public Supplier<SecurityContext> loadContext(HttpServletRequest request) {
-		return () -> (SecurityContext) request.getAttribute(this.requestAttributeName);
+		return () -> getContextOrEmpty(request);
+	}
+
+	private SecurityContext getContextOrEmpty(HttpServletRequest request) {
+		SecurityContext context = getContext(request);
+		return (context != null) ? context : SecurityContextHolder.createEmptyContext();
+	}
+
+	private SecurityContext getContext(HttpServletRequest request) {
+		return (SecurityContext) request.getAttribute(this.requestAttributeName);
 	}
 
 	@Override

+ 15 - 0
web/src/test/java/org/springframework/security/web/context/RequestAttributeSecurityContextRepositoryTests.java

@@ -16,6 +16,8 @@
 
 package org.springframework.security.web.context;
 
+import java.util.function.Supplier;
+
 import org.junit.jupiter.api.Test;
 
 import org.springframework.mock.web.MockHttpServletRequest;
@@ -67,4 +69,17 @@ class RequestAttributeSecurityContextRepositoryTests {
 		assertThat(this.repository.containsContext(this.request)).isTrue();
 	}
 
+	@Test
+	void loadDeferredContextWhenNotPresentThenEmptyContext() {
+		Supplier<SecurityContext> deferredContext = this.repository.loadContext(this.request);
+		assertThat(deferredContext.get()).isEqualTo(SecurityContextHolder.createEmptyContext());
+	}
+
+	@Test
+	void loadContextWhenNotPresentThenEmptyContext() {
+		SecurityContext context = this.repository
+				.loadContext(new HttpRequestResponseHolder(this.request, this.response));
+		assertThat(context).isEqualTo(SecurityContextHolder.createEmptyContext());
+	}
+
 }