Skip to content

Commit 05b788d

Browse files
committed
Use SecurityContextHolderStrategy for Concurrency Filter
Issue gh-11060 Issue gh-11061
1 parent d24a89a commit 05b788d

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurer.java

+1
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ private ConcurrentSessionFilter createConcurrencyFilter(H http) {
400400
concurrentSessionFilter.setLogoutHandlers(logoutHandlers);
401401
}
402402
}
403+
concurrentSessionFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
403404
return concurrentSessionFilter;
404405
}
405406

web/src/main/java/org/springframework/security/web/session/ConcurrentSessionFilter.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 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
import org.springframework.core.log.LogMessage;
3131
import org.springframework.security.core.Authentication;
3232
import org.springframework.security.core.context.SecurityContextHolder;
33+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
3334
import org.springframework.security.core.session.SessionInformation;
3435
import org.springframework.security.core.session.SessionRegistry;
3536
import org.springframework.security.web.RedirectStrategy;
@@ -67,6 +68,9 @@
6768
*/
6869
public class ConcurrentSessionFilter extends GenericFilterBean {
6970

71+
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
72+
.getContextHolderStrategy();
73+
7074
private final SessionRegistry sessionRegistry;
7175

7276
private String expiredUrl;
@@ -162,11 +166,22 @@ protected String determineExpiredUrl(HttpServletRequest request, SessionInformat
162166
}
163167

164168
private void doLogout(HttpServletRequest request, HttpServletResponse response) {
165-
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
169+
Authentication auth = this.securityContextHolderStrategy.getContext().getAuthentication();
166170

167171
this.handlers.logout(request, response, auth);
168172
}
169173

174+
/**
175+
* Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
176+
* the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
177+
*
178+
* @since 5.8
179+
*/
180+
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
181+
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
182+
this.securityContextHolderStrategy = securityContextHolderStrategy;
183+
}
184+
170185
public void setLogoutHandlers(LogoutHandler[] handlers) {
171186
this.handlers = new CompositeLogoutHandler(handlers);
172187
}

web/src/test/java/org/springframework/security/MockSecurityContextHolderStrategy.java

+9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.security;
1818

19+
import org.springframework.security.core.Authentication;
1920
import org.springframework.security.core.context.SecurityContext;
2021
import org.springframework.security.core.context.SecurityContextHolderStrategy;
2122
import org.springframework.security.core.context.SecurityContextImpl;
@@ -24,6 +25,14 @@ public class MockSecurityContextHolderStrategy implements SecurityContextHolderS
2425

2526
private SecurityContext mock;
2627

28+
public MockSecurityContextHolderStrategy() {
29+
30+
}
31+
32+
public MockSecurityContextHolderStrategy(Authentication authentication) {
33+
this.mock = new SecurityContextImpl(authentication);
34+
}
35+
2736
@Override
2837
public void clearContext() {
2938
this.mock = null;

web/src/test/java/org/springframework/security/web/concurrent/ConcurrentSessionFilterTests.java

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -28,7 +28,10 @@
2828
import org.springframework.mock.web.MockHttpServletRequest;
2929
import org.springframework.mock.web.MockHttpServletResponse;
3030
import org.springframework.mock.web.MockHttpSession;
31+
import org.springframework.security.MockSecurityContextHolderStrategy;
32+
import org.springframework.security.authentication.TestingAuthenticationToken;
3133
import org.springframework.security.core.context.SecurityContextHolder;
34+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
3235
import org.springframework.security.core.session.SessionInformation;
3336
import org.springframework.security.core.session.SessionRegistry;
3437
import org.springframework.security.core.session.SessionRegistryImpl;
@@ -46,6 +49,7 @@
4649
import static org.mockito.ArgumentMatchers.eq;
4750
import static org.mockito.BDDMockito.given;
4851
import static org.mockito.Mockito.mock;
52+
import static org.mockito.Mockito.spy;
4953
import static org.mockito.Mockito.verify;
5054
import static org.mockito.Mockito.verifyZeroInteractions;
5155

@@ -266,6 +270,25 @@ public void doFilterWhenCustomLogoutHandlersThenHandlersUsed() throws Exception
266270
verify(handler).logout(eq(request), eq(response), any());
267271
}
268272

273+
@Test
274+
public void doFilterWhenCustomSecurityContextHolderStrategyThenHandlersUsed() throws Exception {
275+
MockHttpServletRequest request = new MockHttpServletRequest();
276+
MockHttpSession session = new MockHttpSession();
277+
request.setSession(session);
278+
MockHttpServletResponse response = new MockHttpServletResponse();
279+
SessionRegistry registry = mock(SessionRegistry.class);
280+
SessionInformation information = new SessionInformation("user", "sessionId",
281+
new Date(System.currentTimeMillis() - 1000));
282+
information.expireNow();
283+
given(registry.getSessionInformation(anyString())).willReturn(information);
284+
ConcurrentSessionFilter filter = new ConcurrentSessionFilter(registry);
285+
SecurityContextHolderStrategy securityContextHolderStrategy = spy(
286+
new MockSecurityContextHolderStrategy(new TestingAuthenticationToken("user", "password")));
287+
filter.setSecurityContextHolderStrategy(securityContextHolderStrategy);
288+
filter.doFilter(request, response, new MockFilterChain());
289+
verify(securityContextHolderStrategy).getContext();
290+
}
291+
269292
@Test
270293
public void setLogoutHandlersWhenNullThenThrowsException() {
271294
ConcurrentSessionFilter filter = new ConcurrentSessionFilter(new SessionRegistryImpl());

0 commit comments

Comments
 (0)