mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-25 05:22:16 +00:00
SEC-2114: Polishing Spring Based Cache
This commit is contained in:
parent
01ea39ce35
commit
6b81f97081
@ -15,9 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.security.acls.domain;
|
package org.springframework.security.acls.domain;
|
||||||
|
|
||||||
import net.sf.ehcache.CacheException;
|
|
||||||
import net.sf.ehcache.Ehcache;
|
|
||||||
import net.sf.ehcache.Element;
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.security.acls.model.AclCache;
|
import org.springframework.security.acls.model.AclCache;
|
||||||
import org.springframework.security.acls.model.MutableAcl;
|
import org.springframework.security.acls.model.MutableAcl;
|
||||||
@ -84,34 +81,12 @@ public class SpringCacheBasedAclCache implements AclCache {
|
|||||||
|
|
||||||
public MutableAcl getFromCache(ObjectIdentity objectIdentity) {
|
public MutableAcl getFromCache(ObjectIdentity objectIdentity) {
|
||||||
Assert.notNull(objectIdentity, "ObjectIdentity required");
|
Assert.notNull(objectIdentity, "ObjectIdentity required");
|
||||||
|
return getFromCache((Object)objectIdentity);
|
||||||
Cache.ValueWrapper element = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
element = cache.get(objectIdentity);
|
|
||||||
} catch (CacheException ignored) {}
|
|
||||||
|
|
||||||
if (element == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return initializeTransientFields((MutableAcl)element.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableAcl getFromCache(Serializable pk) {
|
public MutableAcl getFromCache(Serializable pk) {
|
||||||
Assert.notNull(pk, "Primary key (identifier) required");
|
Assert.notNull(pk, "Primary key (identifier) required");
|
||||||
|
return getFromCache((Object)pk);
|
||||||
Cache.ValueWrapper element = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
element = cache.get(pk);
|
|
||||||
} catch (CacheException ignored) {}
|
|
||||||
|
|
||||||
if (element == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return initializeTransientFields((MutableAcl) element.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putInCache(MutableAcl acl) {
|
public void putInCache(MutableAcl acl) {
|
||||||
@ -127,6 +102,16 @@ public class SpringCacheBasedAclCache implements AclCache {
|
|||||||
cache.put(acl.getId(), acl);
|
cache.put(acl.getId(), acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MutableAcl getFromCache(Object key) {
|
||||||
|
Cache.ValueWrapper element = cache.get(key);
|
||||||
|
|
||||||
|
if (element == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return initializeTransientFields((MutableAcl) element.get());
|
||||||
|
}
|
||||||
|
|
||||||
private MutableAcl initializeTransientFields(MutableAcl value) {
|
private MutableAcl initializeTransientFields(MutableAcl value) {
|
||||||
if (value instanceof AclImpl) {
|
if (value instanceof AclImpl) {
|
||||||
FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value, this.aclAuthorizationStrategy);
|
FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value, this.aclAuthorizationStrategy);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package org.springframework.security.acls.jdbc;
|
package org.springframework.security.acls.jdbc;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
@ -17,15 +16,14 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.util.FieldUtils;
|
import org.springframework.security.util.FieldUtils;
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link org.springframework.security.acls.domain.EhCacheBasedAclCache}
|
* Tests {@link org.springframework.security.acls.domain.SpringCacheBasedAclCache}
|
||||||
*
|
*
|
||||||
* @author Andrei Stefan
|
* @author Marten Deinum
|
||||||
*/
|
*/
|
||||||
public class SpringCacheBasedAclCacheTests {
|
public class SpringCacheBasedAclCacheTests {
|
||||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||||
@ -55,6 +53,7 @@ public class SpringCacheBasedAclCacheTests {
|
|||||||
new SpringCacheBasedAclCache(null, null, null);
|
new SpringCacheBasedAclCache(null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Test
|
@Test
|
||||||
public void cacheOperationsAclWithoutParent() throws Exception {
|
public void cacheOperationsAclWithoutParent() throws Exception {
|
||||||
Cache cache = getCache();
|
Cache cache = getCache();
|
||||||
@ -98,7 +97,7 @@ public class SpringCacheBasedAclCacheTests {
|
|||||||
assertEquals(realCache.size(), 0);
|
assertEquals(realCache.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
@Test
|
@Test
|
||||||
public void cacheOperationsAclWithParent() throws Exception {
|
public void cacheOperationsAclWithParent() throws Exception {
|
||||||
Cache cache = getCache();
|
Cache cache = getCache();
|
||||||
@ -140,33 +139,4 @@ public class SpringCacheBasedAclCacheTests {
|
|||||||
assertNotNull(FieldUtils.getFieldValue(parentAclFromCache, "aclAuthorizationStrategy"));
|
assertNotNull(FieldUtils.getFieldValue(parentAclFromCache, "aclAuthorizationStrategy"));
|
||||||
assertEquals(parentAcl, myCache.getFromCache(identityParent));
|
assertEquals(parentAcl, myCache.getFromCache(identityParent));
|
||||||
}
|
}
|
||||||
|
|
||||||
//~ Inner Classes ==================================================================================================
|
|
||||||
|
|
||||||
private class MockCache implements Cache {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "mockcache";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getNativeCache() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ValueWrapper get(Object key) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void put(Object key, Object value) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void evict(Object key) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ package org.springframework.security.cas.authentication;
|
|||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@ -29,21 +28,24 @@ import org.springframework.util.Assert;
|
|||||||
* @since 3.2
|
* @since 3.2
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SpringCacheBasedTicketCache implements StatelessTicketCache, InitializingBean {
|
public class SpringCacheBasedTicketCache implements StatelessTicketCache {
|
||||||
//~ Static fields/initializers =====================================================================================
|
//~ Static fields/initializers =====================================================================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(SpringCacheBasedTicketCache.class);
|
private static final Log logger = LogFactory.getLog(SpringCacheBasedTicketCache.class);
|
||||||
|
|
||||||
//~ Instance fields ================================================================================================
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
private Cache cache;
|
private final Cache cache;
|
||||||
|
|
||||||
|
//~ Constructors ===================================================================================================
|
||||||
|
|
||||||
|
public SpringCacheBasedTicketCache(Cache cache) throws Exception {
|
||||||
|
Assert.notNull(cache, "cache mandatory");
|
||||||
|
this.cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
|
||||||
Assert.notNull(cache, "cache mandatory");
|
|
||||||
}
|
|
||||||
|
|
||||||
public CasAuthenticationToken getByTicketId(final String serviceTicket) {
|
public CasAuthenticationToken getByTicketId(final String serviceTicket) {
|
||||||
final Cache.ValueWrapper element = serviceTicket != null ? cache.get(serviceTicket) : null;
|
final Cache.ValueWrapper element = serviceTicket != null ? cache.get(serviceTicket) : null;
|
||||||
|
|
||||||
@ -54,10 +56,6 @@ public class SpringCacheBasedTicketCache implements StatelessTicketCache, Initia
|
|||||||
return element == null ? null : (CasAuthenticationToken) element.get();
|
return element == null ? null : (CasAuthenticationToken) element.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cache getCache() {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void putTicketInCache(final CasAuthenticationToken token) {
|
public void putTicketInCache(final CasAuthenticationToken token) {
|
||||||
String key = token.getCredentials().toString();
|
String key = token.getCredentials().toString();
|
||||||
|
|
||||||
@ -79,8 +77,4 @@ public class SpringCacheBasedTicketCache implements StatelessTicketCache, Initia
|
|||||||
public void removeTicketFromCache(final String serviceTicket) {
|
public void removeTicketFromCache(final String serviceTicket) {
|
||||||
cache.evict(serviceTicket);
|
cache.evict(serviceTicket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCache(final Cache cache) {
|
|
||||||
this.cache = cache;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,8 @@
|
|||||||
|
|
||||||
package org.springframework.security.cas.authentication;
|
package org.springframework.security.cas.authentication;
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.cache.Cache;
|
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||||
|
|
||||||
@ -35,6 +33,7 @@ public class SpringCacheBasedTicketCacheTests extends AbstractStatelessTicketCac
|
|||||||
private static CacheManager cacheManager;
|
private static CacheManager cacheManager;
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void initCacheManaer() {
|
public static void initCacheManaer() {
|
||||||
cacheManager = new ConcurrentMapCacheManager();
|
cacheManager = new ConcurrentMapCacheManager();
|
||||||
@ -43,9 +42,7 @@ public class SpringCacheBasedTicketCacheTests extends AbstractStatelessTicketCac
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCacheOperation() throws Exception {
|
public void testCacheOperation() throws Exception {
|
||||||
SpringCacheBasedTicketCache cache = new SpringCacheBasedTicketCache();
|
SpringCacheBasedTicketCache cache = new SpringCacheBasedTicketCache(cacheManager.getCache("castickets"));
|
||||||
cache.setCache(cacheManager.getCache("castickets"));
|
|
||||||
cache.afterPropertiesSet();
|
|
||||||
|
|
||||||
final CasAuthenticationToken token = getToken();
|
final CasAuthenticationToken token = getToken();
|
||||||
|
|
||||||
@ -62,19 +59,8 @@ public class SpringCacheBasedTicketCacheTests extends AbstractStatelessTicketCac
|
|||||||
assertNull(cache.getByTicketId("UNKNOWN_SERVICE_TICKET"));
|
assertNull(cache.getByTicketId("UNKNOWN_SERVICE_TICKET"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testStartupDetectsMissingCache() throws Exception {
|
public void testStartupDetectsMissingCache() throws Exception {
|
||||||
SpringCacheBasedTicketCache cache = new SpringCacheBasedTicketCache();
|
new SpringCacheBasedTicketCache(null);
|
||||||
|
|
||||||
try {
|
|
||||||
cache.afterPropertiesSet();
|
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException expected) {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache myCache = cacheManager.getCache("castickets");
|
|
||||||
cache.setCache(myCache);
|
|
||||||
assertEquals(myCache, cache.getCache());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,18 @@ package org.springframework.security.core.userdetails.cache;
|
|||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.security.core.userdetails.UserCache;
|
import org.springframework.security.core.userdetails.UserCache;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches {@link UserDetails} intances in a Spring defined {@link Cache}.
|
* Caches {@link UserDetails} instances in a Spring defined {@link Cache}.
|
||||||
*
|
*
|
||||||
* @author Marten Deinum
|
* @author Marten Deinum
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public class SpringCacheBasedUserCache implements UserCache, InitializingBean {
|
public class SpringCacheBasedUserCache implements UserCache {
|
||||||
|
|
||||||
|
|
||||||
//~ Static fields/initializers =====================================================================================
|
//~ Static fields/initializers =====================================================================================
|
||||||
@ -23,18 +22,17 @@ public class SpringCacheBasedUserCache implements UserCache, InitializingBean {
|
|||||||
|
|
||||||
//~ Instance fields ================================================================================================
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
private Cache cache;
|
private final Cache cache;
|
||||||
|
|
||||||
|
//~ Constructors ===================================================================================================
|
||||||
|
|
||||||
|
public SpringCacheBasedUserCache(Cache cache) throws Exception {
|
||||||
|
Assert.notNull(cache, "cache mandatory");
|
||||||
|
this.cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
|
||||||
Assert.notNull(cache, "cache mandatory");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cache getCache() {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserDetails getUserFromCache(String username) {
|
public UserDetails getUserFromCache(String username) {
|
||||||
Cache.ValueWrapper element = username != null ? cache.get(username) : null;
|
Cache.ValueWrapper element = username != null ? cache.get(username) : null;
|
||||||
|
|
||||||
@ -67,8 +65,4 @@ public class SpringCacheBasedUserCache implements UserCache, InitializingBean {
|
|||||||
public void removeUserFromCache(String username) {
|
public void removeUserFromCache(String username) {
|
||||||
cache.evict(username);
|
cache.evict(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCache(Cache cache) {
|
|
||||||
this.cache = cache;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -61,9 +61,7 @@ public class SpringCacheBasedUserCacheTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void cacheOperationsAreSuccessful() throws Exception {
|
public void cacheOperationsAreSuccessful() throws Exception {
|
||||||
SpringCacheBasedUserCache cache = new SpringCacheBasedUserCache();
|
SpringCacheBasedUserCache cache = new SpringCacheBasedUserCache(getCache());
|
||||||
cache.setCache(getCache());
|
|
||||||
cache.afterPropertiesSet();
|
|
||||||
|
|
||||||
// Check it gets stored in the cache
|
// Check it gets stored in the cache
|
||||||
cache.putUserInCache(getUser());
|
cache.putUserInCache(getUser());
|
||||||
@ -80,13 +78,6 @@ public class SpringCacheBasedUserCacheTests {
|
|||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void startupDetectsMissingCache() throws Exception {
|
public void startupDetectsMissingCache() throws Exception {
|
||||||
SpringCacheBasedUserCache cache = new SpringCacheBasedUserCache();
|
new SpringCacheBasedUserCache(null);
|
||||||
|
|
||||||
cache.afterPropertiesSet();
|
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
|
|
||||||
Cache myCache = getCache();
|
|
||||||
cache.setCache(myCache);
|
|
||||||
assertEquals(myCache, cache.getCache());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user