Skip to content

Commit 5d75791

Browse files
author
Steve Riesenberg
committed
Add SecurityContextHolderStrategy to new repository
In 6.0, RequestAttributeSecurityContextRepository will be the default implementation of SecurityContextRepository. This commit adds the ability to configure a custom SecurityContextHolderStrategy, similar to other components. Issue gh-11060 Closes gh-11895
1 parent d94677f commit 5d75791

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

web/src/main/java/org/springframework/security/web/context/RequestAttributeSecurityContextRepository.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
import org.springframework.security.core.context.SecurityContext;
2525
import org.springframework.security.core.context.SecurityContextHolder;
26+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
27+
import org.springframework.util.Assert;
2628

2729
/**
2830
* Stores the {@link SecurityContext} on a
@@ -48,6 +50,9 @@ public final class RequestAttributeSecurityContextRepository implements Security
4850

4951
private final String requestAttributeName;
5052

53+
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
54+
.getContextHolderStrategy();
55+
5156
/**
5257
* Creates a new instance using {@link #DEFAULT_REQUEST_ATTR_NAME}.
5358
*/
@@ -81,7 +86,7 @@ public Supplier<SecurityContext> loadContext(HttpServletRequest request) {
8186

8287
private SecurityContext getContextOrEmpty(HttpServletRequest request) {
8388
SecurityContext context = getContext(request);
84-
return (context != null) ? context : SecurityContextHolder.createEmptyContext();
89+
return (context != null) ? context : this.securityContextHolderStrategy.createEmptyContext();
8590
}
8691

8792
private SecurityContext getContext(HttpServletRequest request) {
@@ -93,4 +98,14 @@ public void saveContext(SecurityContext context, HttpServletRequest request, Htt
9398
request.setAttribute(this.requestAttributeName, context);
9499
}
95100

101+
/**
102+
* Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
103+
* the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
104+
* @since 5.8
105+
*/
106+
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
107+
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
108+
this.securityContextHolderStrategy = securityContextHolderStrategy;
109+
}
110+
96111
}

web/src/test/java/org/springframework/security/web/context/RequestAttributeSecurityContextRepositoryTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,15 @@
2525
import org.springframework.security.authentication.TestAuthentication;
2626
import org.springframework.security.core.context.SecurityContext;
2727
import org.springframework.security.core.context.SecurityContextHolder;
28+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
2829
import org.springframework.security.core.context.SecurityContextImpl;
2930

3031
import static org.assertj.core.api.Assertions.assertThat;
32+
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
33+
import static org.mockito.BDDMockito.given;
34+
import static org.mockito.Mockito.mock;
35+
import static org.mockito.Mockito.verify;
36+
import static org.mockito.Mockito.verifyNoMoreInteractions;
3137

3238
/**
3339
* @author Rob Winch
@@ -42,6 +48,15 @@ class RequestAttributeSecurityContextRepositoryTests {
4248

4349
private SecurityContext expectedSecurityContext = new SecurityContextImpl(TestAuthentication.authenticatedUser());
4450

51+
@Test
52+
void setSecurityContextHolderStrategyWhenNullThenThrowsIllegalArgumentException() {
53+
// @formatter:off
54+
assertThatIllegalArgumentException()
55+
.isThrownBy(() -> this.repository.setSecurityContextHolderStrategy(null))
56+
.withMessage("securityContextHolderStrategy cannot be null");
57+
// @formatter:on
58+
}
59+
4560
@Test
4661
void saveContextAndLoadContextThenFound() {
4762
this.repository.saveContext(this.expectedSecurityContext, this.request, this.response);
@@ -82,4 +97,16 @@ void loadContextWhenNotPresentThenEmptyContext() {
8297
assertThat(context).isEqualTo(SecurityContextHolder.createEmptyContext());
8398
}
8499

100+
@Test
101+
void loadContextWhenCustomSecurityContextHolderStrategySetThenUsed() {
102+
SecurityContextHolderStrategy securityContextHolderStrategy = mock(SecurityContextHolderStrategy.class);
103+
given(securityContextHolderStrategy.createEmptyContext()).willReturn(new SecurityContextImpl());
104+
this.repository.setSecurityContextHolderStrategy(securityContextHolderStrategy);
105+
106+
Supplier<SecurityContext> deferredContext = this.repository.loadContext(this.request);
107+
assertThat(deferredContext.get()).isNotNull();
108+
verify(securityContextHolderStrategy).createEmptyContext();
109+
verifyNoMoreInteractions(securityContextHolderStrategy);
110+
}
111+
85112
}

0 commit comments

Comments
 (0)