From 5a0f1d51c3e702b6313a463de0cbe7c26e496f9b Mon Sep 17 00:00:00 2001 From: Marcus Da Coregio Date: Tue, 12 Oct 2021 09:32:34 -0300 Subject: [PATCH] Drop EhCache2 support Issue gh-10363 --- acl/spring-security-acl.gradle | 2 - .../acls/domain/EhCacheBasedAclCache.java | 141 ----------- .../AbstractBasicLookupStrategyTests.java | 64 +++-- .../acls/jdbc/EhCacheBasedAclCacheTests.java | 223 ------------------ .../jdbcMutableAclServiceTests-context.xml | 12 +- cas/spring-security-cas.gradle | 1 - .../EhCacheBasedTicketCache.java | 80 ------- .../EhCacheBasedTicketCacheTests.java | 76 ------ core/spring-security-core.gradle | 1 - .../cache/EhCacheBasedUserCache.java | 81 ------- .../dao/DaoAuthenticationProviderTests.java | 7 +- .../cache/EhCacheBasedUserCacheTests.java | 89 ------- .../spring-security-dependencies.gradle | 1 - 13 files changed, 54 insertions(+), 724 deletions(-) delete mode 100644 acl/src/main/java/org/springframework/security/acls/domain/EhCacheBasedAclCache.java delete mode 100644 acl/src/test/java/org/springframework/security/acls/jdbc/EhCacheBasedAclCacheTests.java delete mode 100644 cas/src/main/java/org/springframework/security/cas/authentication/EhCacheBasedTicketCache.java delete mode 100644 cas/src/test/java/org/springframework/security/cas/authentication/EhCacheBasedTicketCacheTests.java delete mode 100644 core/src/main/java/org/springframework/security/core/userdetails/cache/EhCacheBasedUserCache.java delete mode 100644 core/src/test/java/org/springframework/security/core/userdetails/cache/EhCacheBasedUserCacheTests.java diff --git a/acl/spring-security-acl.gradle b/acl/spring-security-acl.gradle index 8de65558b8..976d8d42db 100644 --- a/acl/spring-security-acl.gradle +++ b/acl/spring-security-acl.gradle @@ -9,8 +9,6 @@ dependencies { api 'org.springframework:spring-jdbc' api 'org.springframework:spring-tx' - optional 'net.sf.ehcache:ehcache' - testImplementation "org.assertj:assertj-core" testImplementation "org.junit.jupiter:junit-jupiter-api" testImplementation "org.junit.jupiter:junit-jupiter-params" diff --git a/acl/src/main/java/org/springframework/security/acls/domain/EhCacheBasedAclCache.java b/acl/src/main/java/org/springframework/security/acls/domain/EhCacheBasedAclCache.java deleted file mode 100644 index 9ad106d7af..0000000000 --- a/acl/src/main/java/org/springframework/security/acls/domain/EhCacheBasedAclCache.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.acls.domain; - -import java.io.Serializable; - -import net.sf.ehcache.CacheException; -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Element; - -import org.springframework.security.acls.model.AclCache; -import org.springframework.security.acls.model.MutableAcl; -import org.springframework.security.acls.model.ObjectIdentity; -import org.springframework.security.acls.model.PermissionGrantingStrategy; -import org.springframework.security.util.FieldUtils; -import org.springframework.util.Assert; - -/** - * Simple implementation of {@link AclCache} that delegates to EH-CACHE. - *

- * Designed to handle the transient fields in {@link AclImpl}. Note that this - * implementation assumes all {@link AclImpl} instances share the same - * {@link PermissionGrantingStrategy} and {@link AclAuthorizationStrategy} instances. - * - * @author Ben Alex - * @deprecated since 5.6. In favor of JCache based implementations - */ -@Deprecated -public class EhCacheBasedAclCache implements AclCache { - - private final Ehcache cache; - - private PermissionGrantingStrategy permissionGrantingStrategy; - - private AclAuthorizationStrategy aclAuthorizationStrategy; - - public EhCacheBasedAclCache(Ehcache cache, PermissionGrantingStrategy permissionGrantingStrategy, - AclAuthorizationStrategy aclAuthorizationStrategy) { - Assert.notNull(cache, "Cache required"); - Assert.notNull(permissionGrantingStrategy, "PermissionGrantingStrategy required"); - Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required"); - this.cache = cache; - this.permissionGrantingStrategy = permissionGrantingStrategy; - this.aclAuthorizationStrategy = aclAuthorizationStrategy; - } - - @Override - public void evictFromCache(Serializable pk) { - Assert.notNull(pk, "Primary key (identifier) required"); - MutableAcl acl = getFromCache(pk); - if (acl != null) { - this.cache.remove(acl.getId()); - this.cache.remove(acl.getObjectIdentity()); - } - } - - @Override - public void evictFromCache(ObjectIdentity objectIdentity) { - Assert.notNull(objectIdentity, "ObjectIdentity required"); - MutableAcl acl = getFromCache(objectIdentity); - if (acl != null) { - this.cache.remove(acl.getId()); - this.cache.remove(acl.getObjectIdentity()); - } - } - - @Override - public MutableAcl getFromCache(ObjectIdentity objectIdentity) { - Assert.notNull(objectIdentity, "ObjectIdentity required"); - try { - Element element = this.cache.get(objectIdentity); - return (element != null) ? initializeTransientFields((MutableAcl) element.getValue()) : null; - } - catch (CacheException ex) { - return null; - } - } - - @Override - public MutableAcl getFromCache(Serializable pk) { - Assert.notNull(pk, "Primary key (identifier) required"); - try { - Element element = this.cache.get(pk); - return (element != null) ? initializeTransientFields((MutableAcl) element.getValue()) : null; - } - catch (CacheException ex) { - return null; - } - } - - @Override - public void putInCache(MutableAcl acl) { - Assert.notNull(acl, "Acl required"); - Assert.notNull(acl.getObjectIdentity(), "ObjectIdentity required"); - Assert.notNull(acl.getId(), "ID required"); - if (this.aclAuthorizationStrategy == null) { - if (acl instanceof AclImpl) { - this.aclAuthorizationStrategy = (AclAuthorizationStrategy) FieldUtils - .getProtectedFieldValue("aclAuthorizationStrategy", acl); - this.permissionGrantingStrategy = (PermissionGrantingStrategy) FieldUtils - .getProtectedFieldValue("permissionGrantingStrategy", acl); - } - } - if ((acl.getParentAcl() != null) && (acl.getParentAcl() instanceof MutableAcl)) { - putInCache((MutableAcl) acl.getParentAcl()); - } - this.cache.put(new Element(acl.getObjectIdentity(), acl)); - this.cache.put(new Element(acl.getId(), acl)); - } - - private MutableAcl initializeTransientFields(MutableAcl value) { - if (value instanceof AclImpl) { - FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value, this.aclAuthorizationStrategy); - FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value, this.permissionGrantingStrategy); - } - if (value.getParentAcl() != null) { - initializeTransientFields((MutableAcl) value.getParentAcl()); - } - return value; - } - - @Override - public void clearCache() { - this.cache.removeAll(); - } - -} diff --git a/acl/src/test/java/org/springframework/security/acls/jdbc/AbstractBasicLookupStrategyTests.java b/acl/src/test/java/org/springframework/security/acls/jdbc/AbstractBasicLookupStrategyTests.java index 4a6b1d695f..9f3f8418ca 100644 --- a/acl/src/test/java/org/springframework/security/acls/jdbc/AbstractBasicLookupStrategyTests.java +++ b/acl/src/test/java/org/springframework/security/acls/jdbc/AbstractBasicLookupStrategyTests.java @@ -16,6 +16,7 @@ package org.springframework.security.acls.jdbc; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -23,15 +24,15 @@ import java.util.UUID; import javax.sql.DataSource; -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Ehcache; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.concurrent.ConcurrentMapCache; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.acls.TargetObject; import org.springframework.security.acls.TargetObjectWithUUID; @@ -41,10 +42,10 @@ import org.springframework.security.acls.domain.BasePermission; import org.springframework.security.acls.domain.ConsoleAuditLogger; import org.springframework.security.acls.domain.DefaultPermissionFactory; import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy; -import org.springframework.security.acls.domain.EhCacheBasedAclCache; import org.springframework.security.acls.domain.GrantedAuthoritySid; import org.springframework.security.acls.domain.ObjectIdentityImpl; import org.springframework.security.acls.domain.PrincipalSid; +import org.springframework.security.acls.domain.SpringCacheBasedAclCache; import org.springframework.security.acls.model.Acl; import org.springframework.security.acls.model.AuditableAccessControlEntry; import org.springframework.security.acls.model.MutableAcl; @@ -55,6 +56,8 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; /** * Tests {@link BasicLookupStrategy} @@ -75,7 +78,7 @@ public abstract class AbstractBasicLookupStrategyTests { private BasicLookupStrategy strategy; - private static CacheManager cacheManager; + private static CacheManagerMock cacheManager; public abstract JdbcTemplate getJdbcTemplate(); @@ -83,14 +86,13 @@ public abstract class AbstractBasicLookupStrategyTests { @BeforeAll public static void initCacheManaer() { - cacheManager = CacheManager.create(); - cacheManager.addCache(new Cache("basiclookuptestcache", 500, false, false, 30, 30)); + cacheManager = new CacheManagerMock(); + cacheManager.addCache("basiclookuptestcache"); } @AfterAll public static void shutdownCacheManager() { - cacheManager.removalAll(); - cacheManager.shutdown(); + cacheManager.clear(); } @BeforeEach @@ -118,11 +120,17 @@ public abstract class AbstractBasicLookupStrategyTests { return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMINISTRATOR")); } - protected EhCacheBasedAclCache aclCache() { - return new EhCacheBasedAclCache(getCache(), new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()), + protected SpringCacheBasedAclCache aclCache() { + return new SpringCacheBasedAclCache(getCache(), new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()), new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_USER"))); } + protected Cache getCache() { + Cache cache = cacheManager.getCacheManager().getCache("basiclookuptestcache"); + cache.clear(); + return cache; + } + @AfterEach public void emptyDatabase() { String query = "DELETE FROM acl_entry;" + "DELETE FROM acl_object_identity WHERE ID = 9;" @@ -134,12 +142,6 @@ public abstract class AbstractBasicLookupStrategyTests { getJdbcTemplate().execute(query); } - protected Ehcache getCache() { - Ehcache cache = cacheManager.getCache("basiclookuptestcache"); - cache.removeAll(); - return cache; - } - @Test public void testAclsRetrievalWithDefaultBatchSize() throws Exception { ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, 100L); @@ -318,4 +320,32 @@ public abstract class AbstractBasicLookupStrategyTests { assertThat(((GrantedAuthoritySid) result).getGrantedAuthority()).isEqualTo("sid"); } + private static final class CacheManagerMock { + + private final List cacheNames; + + private final CacheManager cacheManager; + + private CacheManagerMock() { + this.cacheNames = new ArrayList<>(); + this.cacheManager = mock(CacheManager.class); + given(this.cacheManager.getCacheNames()).willReturn(this.cacheNames); + } + + private CacheManager getCacheManager() { + return this.cacheManager; + } + + private void addCache(String name) { + this.cacheNames.add(name); + Cache cache = new ConcurrentMapCache(name); + given(this.cacheManager.getCache(name)).willReturn(cache); + } + + private void clear() { + this.cacheNames.clear(); + } + + } + } diff --git a/acl/src/test/java/org/springframework/security/acls/jdbc/EhCacheBasedAclCacheTests.java b/acl/src/test/java/org/springframework/security/acls/jdbc/EhCacheBasedAclCacheTests.java deleted file mode 100644 index 35545abae2..0000000000 --- a/acl/src/test/java/org/springframework/security/acls/jdbc/EhCacheBasedAclCacheTests.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.acls.jdbc; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.List; - -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Element; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.security.acls.domain.AclAuthorizationStrategy; -import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl; -import org.springframework.security.acls.domain.AclImpl; -import org.springframework.security.acls.domain.ConsoleAuditLogger; -import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy; -import org.springframework.security.acls.domain.EhCacheBasedAclCache; -import org.springframework.security.acls.domain.ObjectIdentityImpl; -import org.springframework.security.acls.model.MutableAcl; -import org.springframework.security.acls.model.ObjectIdentity; -import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.util.FieldUtils; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * Tests {@link EhCacheBasedAclCache} - * - * @author Andrei Stefan - */ -@ExtendWith(MockitoExtension.class) -public class EhCacheBasedAclCacheTests { - - private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject"; - - @Mock - private Ehcache cache; - - @Captor - private ArgumentCaptor element; - - private EhCacheBasedAclCache myCache; - - private MutableAcl acl; - - @BeforeEach - public void setup() { - this.myCache = new EhCacheBasedAclCache(this.cache, - new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()), - new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_USER"))); - ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100L); - AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl( - new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"), - new SimpleGrantedAuthority("ROLE_GENERAL")); - this.acl = new AclImpl(identity, 1L, aclAuthorizationStrategy, new ConsoleAuditLogger()); - } - - @AfterEach - public void cleanup() { - SecurityContextHolder.clearContext(); - } - - @Test - public void constructorRejectsNullParameters() { - assertThatIllegalArgumentException().isThrownBy( - () -> new EhCacheBasedAclCache(null, new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()), - new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_USER")))); - } - - @Test - public void methodsRejectNullParameters() { - assertThatIllegalArgumentException().isThrownBy(() -> this.myCache.evictFromCache((Serializable) null)); - assertThatIllegalArgumentException().isThrownBy(() -> this.myCache.evictFromCache((ObjectIdentity) null)); - assertThatIllegalArgumentException().isThrownBy(() -> this.myCache.getFromCache((Serializable) null)); - assertThatIllegalArgumentException().isThrownBy(() -> this.myCache.getFromCache((ObjectIdentity) null)); - assertThatIllegalArgumentException().isThrownBy(() -> this.myCache.putInCache(null)); - } - - // SEC-527 - @Test - public void testDiskSerializationOfMutableAclObjectInstance() throws Exception { - // Serialization test - File file = File.createTempFile("SEC_TEST", ".object"); - FileOutputStream fos = new FileOutputStream(file); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(this.acl); - oos.close(); - FileInputStream fis = new FileInputStream(file); - ObjectInputStream ois = new ObjectInputStream(fis); - MutableAcl retrieved = (MutableAcl) ois.readObject(); - ois.close(); - assertThat(retrieved).isEqualTo(this.acl); - Object retrieved1 = FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy", retrieved); - assertThat(retrieved1).isNull(); - Object retrieved2 = FieldUtils.getProtectedFieldValue("permissionGrantingStrategy", retrieved); - assertThat(retrieved2).isNull(); - } - - @Test - public void clearCache() { - this.myCache.clearCache(); - verify(this.cache).removeAll(); - } - - @Test - public void putInCache() { - this.myCache.putInCache(this.acl); - verify(this.cache, times(2)).put(this.element.capture()); - assertThat(this.element.getValue().getKey()).isEqualTo(this.acl.getId()); - assertThat(this.element.getValue().getObjectValue()).isEqualTo(this.acl); - assertThat(this.element.getAllValues().get(0).getKey()).isEqualTo(this.acl.getObjectIdentity()); - assertThat(this.element.getAllValues().get(0).getObjectValue()).isEqualTo(this.acl); - } - - @Test - public void putInCacheAclWithParent() { - Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL"); - auth.setAuthenticated(true); - SecurityContextHolder.getContext().setAuthentication(auth); - ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, 2L); - AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl( - new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"), - new SimpleGrantedAuthority("ROLE_GENERAL")); - MutableAcl parentAcl = new AclImpl(identityParent, 2L, aclAuthorizationStrategy, new ConsoleAuditLogger()); - this.acl.setParent(parentAcl); - this.myCache.putInCache(this.acl); - verify(this.cache, times(4)).put(this.element.capture()); - List allValues = this.element.getAllValues(); - assertThat(allValues.get(0).getKey()).isEqualTo(parentAcl.getObjectIdentity()); - assertThat(allValues.get(0).getObjectValue()).isEqualTo(parentAcl); - assertThat(allValues.get(1).getKey()).isEqualTo(parentAcl.getId()); - assertThat(allValues.get(1).getObjectValue()).isEqualTo(parentAcl); - assertThat(allValues.get(2).getKey()).isEqualTo(this.acl.getObjectIdentity()); - assertThat(allValues.get(2).getObjectValue()).isEqualTo(this.acl); - assertThat(allValues.get(3).getKey()).isEqualTo(this.acl.getId()); - assertThat(allValues.get(3).getObjectValue()).isEqualTo(this.acl); - } - - @Test - public void getFromCacheSerializable() { - given(this.cache.get(this.acl.getId())).willReturn(new Element(this.acl.getId(), this.acl)); - assertThat(this.myCache.getFromCache(this.acl.getId())).isEqualTo(this.acl); - } - - @Test - public void getFromCacheSerializablePopulatesTransient() { - given(this.cache.get(this.acl.getId())).willReturn(new Element(this.acl.getId(), this.acl)); - this.myCache.putInCache(this.acl); - ReflectionTestUtils.setField(this.acl, "permissionGrantingStrategy", null); - ReflectionTestUtils.setField(this.acl, "aclAuthorizationStrategy", null); - MutableAcl fromCache = this.myCache.getFromCache(this.acl.getId()); - assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy")).isNotNull(); - assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy")).isNotNull(); - } - - @Test - public void getFromCacheObjectIdentity() { - given(this.cache.get(this.acl.getId())).willReturn(new Element(this.acl.getId(), this.acl)); - assertThat(this.myCache.getFromCache(this.acl.getId())).isEqualTo(this.acl); - } - - @Test - public void getFromCacheObjectIdentityPopulatesTransient() { - given(this.cache.get(this.acl.getObjectIdentity())).willReturn(new Element(this.acl.getId(), this.acl)); - this.myCache.putInCache(this.acl); - ReflectionTestUtils.setField(this.acl, "permissionGrantingStrategy", null); - ReflectionTestUtils.setField(this.acl, "aclAuthorizationStrategy", null); - MutableAcl fromCache = this.myCache.getFromCache(this.acl.getObjectIdentity()); - assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy")).isNotNull(); - assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy")).isNotNull(); - } - - @Test - public void evictCacheSerializable() { - given(this.cache.get(this.acl.getObjectIdentity())).willReturn(new Element(this.acl.getId(), this.acl)); - this.myCache.evictFromCache(this.acl.getObjectIdentity()); - verify(this.cache).remove(this.acl.getId()); - verify(this.cache).remove(this.acl.getObjectIdentity()); - } - - @Test - public void evictCacheObjectIdentity() { - given(this.cache.get(this.acl.getId())).willReturn(new Element(this.acl.getId(), this.acl)); - this.myCache.evictFromCache(this.acl.getId()); - verify(this.cache).remove(this.acl.getId()); - verify(this.cache).remove(this.acl.getObjectIdentity()); - } - -} diff --git a/acl/src/test/resources/jdbcMutableAclServiceTests-context.xml b/acl/src/test/resources/jdbcMutableAclServiceTests-context.xml index 457c183d56..d23a727141 100644 --- a/acl/src/test/resources/jdbcMutableAclServiceTests-context.xml +++ b/acl/src/test/resources/jdbcMutableAclServiceTests-context.xml @@ -13,16 +13,10 @@ - + - - - - - - - - + + diff --git a/cas/spring-security-cas.gradle b/cas/spring-security-cas.gradle index 4df4d66a6f..f340ec7dda 100644 --- a/cas/spring-security-cas.gradle +++ b/cas/spring-security-cas.gradle @@ -11,7 +11,6 @@ dependencies { api 'org.springframework:spring-web' optional 'com.fasterxml.jackson.core:jackson-databind' - optional 'net.sf.ehcache:ehcache' provided 'jakarta.servlet:jakarta.servlet-api' diff --git a/cas/src/main/java/org/springframework/security/cas/authentication/EhCacheBasedTicketCache.java b/cas/src/main/java/org/springframework/security/cas/authentication/EhCacheBasedTicketCache.java deleted file mode 100644 index 595c0d23f2..0000000000 --- a/cas/src/main/java/org/springframework/security/cas/authentication/EhCacheBasedTicketCache.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.cas.authentication; - -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Element; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.log.LogMessage; -import org.springframework.util.Assert; - -/** - * Caches tickets using a Spring IoC defined - * EHCACHE. - * - * @author Ben Alex - * @deprecated since 5.6. In favor of JCache based implementations - */ -@Deprecated -public class EhCacheBasedTicketCache implements StatelessTicketCache, InitializingBean { - - private static final Log logger = LogFactory.getLog(EhCacheBasedTicketCache.class); - - private Ehcache cache; - - @Override - public void afterPropertiesSet() { - Assert.notNull(this.cache, "cache mandatory"); - } - - @Override - public CasAuthenticationToken getByTicketId(final String serviceTicket) { - final Element element = this.cache.get(serviceTicket); - logger.debug(LogMessage.of(() -> "Cache hit: " + (element != null) + "; service ticket: " + serviceTicket)); - return (element != null) ? (CasAuthenticationToken) element.getValue() : null; - } - - public Ehcache getCache() { - return this.cache; - } - - @Override - public void putTicketInCache(final CasAuthenticationToken token) { - final Element element = new Element(token.getCredentials().toString(), token); - logger.debug(LogMessage.of(() -> "Cache put: " + element.getKey())); - this.cache.put(element); - } - - @Override - public void removeTicketFromCache(final CasAuthenticationToken token) { - logger.debug(LogMessage.of(() -> "Cache remove: " + token.getCredentials().toString())); - this.removeTicketFromCache(token.getCredentials().toString()); - } - - @Override - public void removeTicketFromCache(final String serviceTicket) { - this.cache.remove(serviceTicket); - } - - public void setCache(final Ehcache cache) { - this.cache = cache; - } - -} diff --git a/cas/src/test/java/org/springframework/security/cas/authentication/EhCacheBasedTicketCacheTests.java b/cas/src/test/java/org/springframework/security/cas/authentication/EhCacheBasedTicketCacheTests.java deleted file mode 100644 index c824eef4bc..0000000000 --- a/cas/src/test/java/org/springframework/security/cas/authentication/EhCacheBasedTicketCacheTests.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.cas.authentication; - -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Ehcache; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests {@link EhCacheBasedTicketCache}. - * - * @author Ben Alex - */ -public class EhCacheBasedTicketCacheTests extends AbstractStatelessTicketCacheTests { - - private static CacheManager cacheManager; - - @BeforeAll - public static void initCacheManaer() { - cacheManager = CacheManager.create(); - cacheManager.addCache(new Cache("castickets", 500, false, false, 30, 30)); - } - - @AfterAll - public static void shutdownCacheManager() { - cacheManager.removalAll(); - cacheManager.shutdown(); - } - - @Test - public void testCacheOperation() throws Exception { - EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache(); - cache.setCache(cacheManager.getCache("castickets")); - cache.afterPropertiesSet(); - final CasAuthenticationToken token = getToken(); - // Check it gets stored in the cache - cache.putTicketInCache(token); - assertThat(cache.getByTicketId("ST-0-ER94xMJmn6pha35CQRoZ")).isEqualTo(token); - // Check it gets removed from the cache - cache.removeTicketFromCache(getToken()); - assertThat(cache.getByTicketId("ST-0-ER94xMJmn6pha35CQRoZ")).isNull(); - // Check it doesn't return values for null or unknown service tickets - assertThat(cache.getByTicketId(null)).isNull(); - assertThat(cache.getByTicketId("UNKNOWN_SERVICE_TICKET")).isNull(); - } - - @Test - public void testStartupDetectsMissingCache() throws Exception { - EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache(); - assertThatIllegalArgumentException().isThrownBy(cache::afterPropertiesSet); - Ehcache myCache = cacheManager.getCache("castickets"); - cache.setCache(myCache); - assertThat(cache.getCache()).isEqualTo(myCache); - } - -} diff --git a/core/spring-security-core.gradle b/core/spring-security-core.gradle index 4d44183793..173b5baba1 100644 --- a/core/spring-security-core.gradle +++ b/core/spring-security-core.gradle @@ -14,7 +14,6 @@ dependencies { optional 'com.fasterxml.jackson.core:jackson-databind' optional 'io.projectreactor:reactor-core' optional 'jakarta.annotation:jakarta.annotation-api' - optional 'net.sf.ehcache:ehcache' optional 'org.aspectj:aspectjrt' optional 'org.springframework:spring-jdbc' optional 'org.springframework:spring-tx' diff --git a/core/src/main/java/org/springframework/security/core/userdetails/cache/EhCacheBasedUserCache.java b/core/src/main/java/org/springframework/security/core/userdetails/cache/EhCacheBasedUserCache.java deleted file mode 100644 index 1aba15b218..0000000000 --- a/core/src/main/java/org/springframework/security/core/userdetails/cache/EhCacheBasedUserCache.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.core.userdetails.cache; - -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Element; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.log.LogMessage; -import org.springframework.security.core.userdetails.UserCache; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.util.Assert; - -/** - * Caches User objects using a Spring IoC defined - * EHCACHE. - * - * @author Ben Alex - * @deprecated since 5.6. In favor of JCache based implementations - */ -@Deprecated -public class EhCacheBasedUserCache implements UserCache, InitializingBean { - - private static final Log logger = LogFactory.getLog(EhCacheBasedUserCache.class); - - private Ehcache cache; - - @Override - public void afterPropertiesSet() { - Assert.notNull(this.cache, "cache mandatory"); - } - - public Ehcache getCache() { - return this.cache; - } - - @Override - public UserDetails getUserFromCache(String username) { - Element element = this.cache.get(username); - logger.debug(LogMessage.of(() -> "Cache hit: " + (element != null) + "; username: " + username)); - return (element != null) ? (UserDetails) element.getValue() : null; - } - - @Override - public void putUserInCache(UserDetails user) { - Element element = new Element(user.getUsername(), user); - logger.debug(LogMessage.of(() -> "Cache put: " + element.getKey())); - this.cache.put(element); - } - - public void removeUserFromCache(UserDetails user) { - logger.debug(LogMessage.of(() -> "Cache remove: " + user.getUsername())); - this.removeUserFromCache(user.getUsername()); - } - - @Override - public void removeUserFromCache(String username) { - this.cache.remove(username); - } - - public void setCache(Ehcache cache) { - this.cache = cache; - } - -} diff --git a/core/src/test/java/org/springframework/security/authentication/dao/DaoAuthenticationProviderTests.java b/core/src/test/java/org/springframework/security/authentication/dao/DaoAuthenticationProviderTests.java index 1771721b7f..4292ce3703 100644 --- a/core/src/test/java/org/springframework/security/authentication/dao/DaoAuthenticationProviderTests.java +++ b/core/src/test/java/org/springframework/security/authentication/dao/DaoAuthenticationProviderTests.java @@ -22,6 +22,7 @@ import java.util.List; import org.junit.jupiter.api.Test; +import org.springframework.cache.Cache; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.security.authentication.AccountExpiredException; import org.springframework.security.authentication.AuthenticationServiceException; @@ -41,8 +42,8 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsPasswordService; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache; import org.springframework.security.core.userdetails.cache.NullUserCache; +import org.springframework.security.core.userdetails.cache.SpringCacheBasedUserCache; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.NoOpPasswordEncoder; @@ -326,8 +327,8 @@ public class DaoAuthenticationProviderTests { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setPasswordEncoder(new BCryptPasswordEncoder()); assertThat(provider.getPasswordEncoder().getClass()).isEqualTo(BCryptPasswordEncoder.class); - provider.setUserCache(new EhCacheBasedUserCache()); - assertThat(provider.getUserCache().getClass()).isEqualTo(EhCacheBasedUserCache.class); + provider.setUserCache(new SpringCacheBasedUserCache(mock(Cache.class))); + assertThat(provider.getUserCache().getClass()).isEqualTo(SpringCacheBasedUserCache.class); assertThat(provider.isForcePrincipalAsString()).isFalse(); provider.setForcePrincipalAsString(true); assertThat(provider.isForcePrincipalAsString()).isTrue(); diff --git a/core/src/test/java/org/springframework/security/core/userdetails/cache/EhCacheBasedUserCacheTests.java b/core/src/test/java/org/springframework/security/core/userdetails/cache/EhCacheBasedUserCacheTests.java deleted file mode 100644 index 907290dd63..0000000000 --- a/core/src/test/java/org/springframework/security/core/userdetails/cache/EhCacheBasedUserCacheTests.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.core.userdetails.cache; - -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Ehcache; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.userdetails.User; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests {@link EhCacheBasedUserCache}. - * - * @author Ben Alex - */ -public class EhCacheBasedUserCacheTests { - - private static CacheManager cacheManager; - - @BeforeAll - public static void initCacheManaer() { - cacheManager = CacheManager.create(); - cacheManager.addCache(new Cache("ehcacheusercachetests", 500, false, false, 30, 30)); - } - - @AfterAll - public static void shutdownCacheManager() { - cacheManager.removalAll(); - cacheManager.shutdown(); - } - - private Ehcache getCache() { - Ehcache cache = cacheManager.getCache("ehcacheusercachetests"); - cache.removeAll(); - return cache; - } - - private User getUser() { - return new User("john", "password", true, true, true, true, - AuthorityUtils.createAuthorityList("ROLE_ONE", "ROLE_TWO")); - } - - @Test - public void cacheOperationsAreSuccessful() throws Exception { - EhCacheBasedUserCache cache = new EhCacheBasedUserCache(); - cache.setCache(getCache()); - cache.afterPropertiesSet(); - // Check it gets stored in the cache - cache.putUserInCache(getUser()); - assertThat(getUser().getPassword()).isEqualTo(cache.getUserFromCache(getUser().getUsername()).getPassword()); - // Check it gets removed from the cache - cache.removeUserFromCache(getUser()); - assertThat(cache.getUserFromCache(getUser().getUsername())).isNull(); - // Check it doesn't return values for null or unknown users - assertThat(cache.getUserFromCache(null)).isNull(); - assertThat(cache.getUserFromCache("UNKNOWN_USER")).isNull(); - } - - @Test - public void startupDetectsMissingCache() throws Exception { - EhCacheBasedUserCache cache = new EhCacheBasedUserCache(); - assertThatIllegalArgumentException().isThrownBy(cache::afterPropertiesSet); - Ehcache myCache = getCache(); - cache.setCache(myCache); - assertThat(cache.getCache()).isEqualTo(myCache); - } - -} diff --git a/dependencies/spring-security-dependencies.gradle b/dependencies/spring-security-dependencies.gradle index a38ccc8f29..fd7f082982 100644 --- a/dependencies/spring-security-dependencies.gradle +++ b/dependencies/spring-security-dependencies.gradle @@ -34,7 +34,6 @@ dependencies { api "jakarta.xml.bind:jakarta.xml.bind-api:3.0.1" api "jakarta.persistence:jakarta.persistence-api:3.0.0" api "ldapsdk:ldapsdk:4.1" - api "net.sf.ehcache:ehcache:2.10.9.2" api "net.sourceforge.htmlunit:htmlunit:2.54.0" api "net.sourceforge.nekohtml:nekohtml:1.9.22" api "org.apache.directory.server:apacheds-core-entry:1.5.5"