Skip to content

Commit 52dc120

Browse files
committed
Use SecurityContextHolderStrategy for ACL
Issue gh-11060
1 parent 94f51d0 commit 52dc120

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed

acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
import org.springframework.security.core.Authentication;
2828
import org.springframework.security.core.GrantedAuthority;
2929
import org.springframework.security.core.authority.AuthorityUtils;
30+
import org.springframework.security.core.context.SecurityContext;
3031
import org.springframework.security.core.context.SecurityContextHolder;
32+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
3133
import org.springframework.util.Assert;
3234

3335
/**
@@ -46,6 +48,9 @@
4648
*/
4749
public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
4850

51+
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
52+
.getContextHolderStrategy();
53+
4954
private final GrantedAuthority gaGeneralChanges;
5055

5156
private final GrantedAuthority gaModifyAuditing;
@@ -81,12 +86,12 @@ public AclAuthorizationStrategyImpl(GrantedAuthority... auths) {
8186

8287
@Override
8388
public void securityCheck(Acl acl, int changeType) {
84-
if ((SecurityContextHolder.getContext() == null)
85-
|| (SecurityContextHolder.getContext().getAuthentication() == null)
86-
|| !SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
89+
SecurityContext context = this.securityContextHolderStrategy.getContext();
90+
if ((context == null) || (context.getAuthentication() == null)
91+
|| !context.getAuthentication().isAuthenticated()) {
8792
throw new AccessDeniedException("Authenticated principal required to operate with ACLs");
8893
}
89-
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
94+
Authentication authentication = context.getAuthentication();
9095
// Check if authorized by virtue of ACL ownership
9196
Sid currentUser = createCurrentUser(authentication);
9297
if (currentUser.equals(acl.getOwner())
@@ -146,4 +151,15 @@ public void setSidRetrievalStrategy(SidRetrievalStrategy sidRetrievalStrategy) {
146151
this.sidRetrievalStrategy = sidRetrievalStrategy;
147152
}
148153

154+
/**
155+
* Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
156+
* the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
157+
*
158+
* @since 5.8
159+
*/
160+
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
161+
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
162+
this.securityContextHolderStrategy = securityContextHolderStrategy;
163+
}
164+
149165
}

acl/src/main/java/org/springframework/security/acls/jdbc/JdbcMutableAclService.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.springframework.security.acls.model.Sid;
4141
import org.springframework.security.core.Authentication;
4242
import org.springframework.security.core.context.SecurityContextHolder;
43+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
4344
import org.springframework.transaction.support.TransactionSynchronizationManager;
4445
import org.springframework.util.Assert;
4546

@@ -64,6 +65,9 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
6465

6566
private static final String DEFAULT_INSERT_INTO_ACL_CLASS_WITH_ID = "insert into acl_class (class, class_id_type) values (?, ?)";
6667

68+
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
69+
.getContextHolderStrategy();
70+
6771
private boolean foreignKeysInDatabase = true;
6872

6973
private final AclCache aclCache;
@@ -115,7 +119,7 @@ public MutableAcl createAcl(ObjectIdentity objectIdentity) throws AlreadyExistsE
115119

116120
// Need to retrieve the current principal, in order to know who "owns" this ACL
117121
// (can be changed later on)
118-
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
122+
Authentication auth = this.securityContextHolderStrategy.getContext().getAuthentication();
119123
PrincipalSid sid = new PrincipalSid(auth);
120124

121125
// Create the acl_object_identity row
@@ -473,4 +477,15 @@ public void setAclClassIdSupported(boolean aclClassIdSupported) {
473477
}
474478
}
475479

480+
/**
481+
* Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
482+
* the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
483+
*
484+
* @since 5.8
485+
*/
486+
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
487+
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
488+
this.securityContextHolderStrategy = securityContextHolderStrategy;
489+
}
490+
476491
}

acl/src/test/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImplTests.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 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.
@@ -29,9 +29,13 @@
2929
import org.springframework.security.authentication.TestingAuthenticationToken;
3030
import org.springframework.security.core.GrantedAuthority;
3131
import org.springframework.security.core.authority.SimpleGrantedAuthority;
32+
import org.springframework.security.core.context.SecurityContext;
3233
import org.springframework.security.core.context.SecurityContextHolder;
34+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
35+
import org.springframework.security.core.context.SecurityContextImpl;
3336

3437
import static org.mockito.BDDMockito.given;
38+
import static org.mockito.Mockito.verify;
3539

3640
/**
3741
* @author Rob Winch
@@ -40,9 +44,14 @@
4044
@ExtendWith(MockitoExtension.class)
4145
public class AclAuthorizationStrategyImplTests {
4246

47+
SecurityContext context;
48+
4349
@Mock
4450
Acl acl;
4551

52+
@Mock
53+
SecurityContextHolderStrategy securityContextHolderStrategy;
54+
4655
GrantedAuthority authority;
4756

4857
AclAuthorizationStrategyImpl strategy;
@@ -53,7 +62,8 @@ public void setup() {
5362
TestingAuthenticationToken authentication = new TestingAuthenticationToken("foo", "bar",
5463
Arrays.asList(this.authority));
5564
authentication.setAuthenticated(true);
56-
SecurityContextHolder.getContext().setAuthentication(authentication);
65+
this.context = new SecurityContextImpl(authentication);
66+
SecurityContextHolder.setContext(this.context);
5767
}
5868

5969
@AfterEach
@@ -76,6 +86,16 @@ public void securityCheckWhenAclOwnedByGrantedAuthority() {
7686
this.strategy.securityCheck(this.acl, AclAuthorizationStrategy.CHANGE_GENERAL);
7787
}
7888

89+
@Test
90+
public void securityCheckWhenCustomSecurityContextHolderStrategyThenUses() {
91+
given(this.securityContextHolderStrategy.getContext()).willReturn(this.context);
92+
given(this.acl.getOwner()).willReturn(new GrantedAuthoritySid("ROLE_AUTH"));
93+
this.strategy = new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_SYSTEM_ADMIN"));
94+
this.strategy.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
95+
this.strategy.securityCheck(this.acl, AclAuthorizationStrategy.CHANGE_GENERAL);
96+
verify(this.securityContextHolderStrategy).getContext();
97+
}
98+
7999
@SuppressWarnings("serial")
80100
class CustomAuthority implements GrantedAuthority {
81101

acl/src/test/java/org/springframework/security/acls/jdbc/JdbcMutableAclServiceTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@
4848
import org.springframework.security.acls.sid.CustomSid;
4949
import org.springframework.security.authentication.TestingAuthenticationToken;
5050
import org.springframework.security.core.Authentication;
51+
import org.springframework.security.core.context.SecurityContext;
5152
import org.springframework.security.core.context.SecurityContextHolder;
53+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
54+
import org.springframework.security.core.context.SecurityContextImpl;
5255
import org.springframework.test.context.ContextConfiguration;
5356
import org.springframework.test.context.junit.jupiter.SpringExtension;
5457
import org.springframework.test.context.transaction.AfterTransaction;
@@ -59,7 +62,9 @@
5962
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
6063
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
6164
import static org.mockito.BDDMockito.given;
65+
import static org.mockito.Mockito.mock;
6266
import static org.mockito.Mockito.spy;
67+
import static org.mockito.Mockito.verify;
6368

6469
/**
6570
* Integration tests the ACL system using an in-memory database.
@@ -350,6 +355,19 @@ public void identityWithIntegerIdIsSupportedByCreateAcl() {
350355
assertThat(this.jdbcMutableAclService.readAclById(new ObjectIdentityImpl(TARGET_CLASS, 101L))).isNotNull();
351356
}
352357

358+
@Test
359+
@Transactional
360+
public void createAclWhenCustomSecurityContextHolderStrategyThenUses() {
361+
SecurityContextHolderStrategy securityContextHolderStrategy = mock(SecurityContextHolderStrategy.class);
362+
SecurityContext context = new SecurityContextImpl(this.auth);
363+
given(securityContextHolderStrategy.getContext()).willReturn(context);
364+
JdbcMutableAclService service = new JdbcMutableAclService(this.dataSource, this.lookupStrategy, this.aclCache);
365+
service.setSecurityContextHolderStrategy(securityContextHolderStrategy);
366+
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 101);
367+
service.createAcl(oid);
368+
verify(securityContextHolderStrategy).getContext();
369+
}
370+
353371
/**
354372
* SEC-655
355373
*/

0 commit comments

Comments
 (0)