2 回答
TA贡献1719条经验 获得超6个赞
我遇到过同样的问题。
就我而言,ACL缓存脏了。每次测试后,我必须清除缓存,然后所有测试都以绿色运行,即使同时调用也是如此。
我为此创建了一个TestExcutionListener。只需用它注释您的抽象Test类:
@TestExecutionListeners(
value = ClearAclCacheTestExecutionListener.class,
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
public class AbstractTest{...}
public class ClearAclCacheTestExecutionListener extends AbstractTestExecutionListener {
@Autowired
private AclCache aclCache;
@Override
public void beforeTestClass(TestContext testContext) {
testContext.getApplicationContext()
.getAutowireCapableBeanFactory()
.autowireBean(this);
}
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
super.afterTestMethod(testContext);
aclCache.clearCache();
}
}
TA贡献1921条经验 获得超9个赞
由于这个问题并没有那么受欢迎,因此我尝试了一种不同的方法,该方法似乎非常有用:-)
首先,我创建了一个新的ACLService类,以隔离与JdbcMutableAclService的所有交互。
package com.roberto.security.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.acls.model.*;
import org.springframework.stereotype.Service;
/**
* Service class to handle ACL permissions.
*/
@Service
public class ACLService {
private final MutableAclService mutableAclService;
@Autowired
public ACLService(MutableAclService mutableAclService) {
this.mutableAclService = mutableAclService;
}
/**
* Insert an ACL entry
* @param oid represents the model object
* @param recipient represents the principal (user, group of users, etc)
* @param permission quite explicit name...
* @return the new ACL database entry
*/
public MutableAcl addPermission(ObjectIdentity oid, Sid recipient, Permission permission) {
MutableAcl acl;
try {
acl = (MutableAcl) mutableAclService.readAclById(oid);
} catch (NotFoundException nfe) {
acl = mutableAclService.createAcl(oid);
}
acl.insertAce(acl.getEntries().size(), permission, recipient, true);
return mutableAclService.updateAcl(acl);
}
}
然后,我创建了另一个集成测试,该测试可以正常运行,而没有IllegalStateException。现在,我只需要从我的引导程序类中调用它即可。
package com.roberto.security.service;
import com.roberto.model.TimeSheet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.*;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import static org.junit.Assert.*;
import static org.springframework.test.annotation.DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD;
/**
* This test handles basic interaction between our codebase
* Spring Security ACL and the underlying database model
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class ACLServiceIntegrationTest {
private Authentication authentication;
private ObjectIdentity oid ;
private Sid sid;
private Permission administration = BasePermission.ADMINISTRATION;
@Autowired
private ACLService aclService;
@Autowired
private MutableAclService mutableAclService;
@Autowired
private PermissionEvaluator permissionEvaluator;
@Before
public void setUp() {
authentication = TestSecurityContextHolder.getContext().getAuthentication();
sid = new PrincipalSid(((JwtUser) authentication.getPrincipal()).getUsername());
oid = new ObjectIdentityImpl(TimeSheet.class, 1);
}
@Test
@WithUserDetails("admin")
public void testBeans() {
assertNotNull(aclService);
assertNotNull(mutableAclService);
assertNotNull(permissionEvaluator);
}
@Test
@Transactional
@WithUserDetails("admin")
@DirtiesContext(methodMode = AFTER_METHOD)
public void addPermissionIntegrationTest() {
assertFalse(permissionEvaluator.hasPermission(authentication, oid.getIdentifier(), oid.getType(), administration));
MutableAcl acl = aclService.addPermission(oi, sid, administration);
assertTrue(permissionEvaluator.hasPermission(authentication, oid.getIdentifier(), oid.getType(), administration));
assertEquals(TimeSheet.class.toString().split(" ")[1], acl.getObjectIdentity().getType());
assertTrue(acl.getEntries().stream().anyMatch(e -> e.getSid().equals(sid) && e.getPermission().equals(administration)));
assertTrue(acl.isGranted(List.of(administration), List.of(sid), true));
}
}
添加回答
举报