shiro cache instance code
- 2020-06-15 10:59:45
- OfStack
Shiro provides Cache abstraction similar to Spring, that is, Shiro does not implement Cache itself, but abstracts Cache to facilitate the replacement of different underlying Cache implementations.
Cache Interface provided by Shiro:
Java code
public interface Cache<K, V> {
// According to the Key Gets the value in the cache
public V get(K key) throws CacheException;
// Put it in the cache key-value , returns the previous value in the cache
public V put(K key, V value) throws CacheException;
// Remove from cache key Returns the corresponding value
public V remove(K key) throws CacheException;
// Clear the entire cache
public void clear() throws CacheException;
// Return cache size
public int size();
// Gets all of the items in the cache key
public Set<K> keys();
// Gets all of the items in the cache value
public Collection<V> values();
}
CacheManager interface provided by Shiro:
Java code
public interface CacheManager {
// Gets by the cache name 1 a Cache
public <K, V> Cache<K, V> getCache(String name) throws CacheException;
}
Shiro also provides CacheManagerAware for injecting CacheManager:
Java code
public interface CacheManagerAware {
// injection CacheManager
void setCacheManager(CacheManager cacheManager);
}
The corresponding component within Shiro (DefaultSecurityManager) automatically detects whether the corresponding object (such as Realm) implements CacheManagerAware and infuses the corresponding CacheManager automatically.
Realm cache
Shiro provides CachingRealm, which implements CacheManagerAware interface and provides some basic implementations of caching. In addition, AuthenticatingRealm and AuthorizingRealm provide caching of AuthenticationInfo and AuthorizationInfo information, respectively.
ini configuration
Java code
userRealm=com.github.zhangkaitao.shiro.chapter11.realm.UserRealm
userRealm.credentialsMatcher=$credentialsMatcher
userRealm.cachingEnabled=true
userRealm.authenticationCachingEnabled=true
userRealm.authenticationCacheName=authenticationCache
userRealm.authorizationCachingEnabled=true
userRealm.authorizationCacheName=authorizationCache
securityManager.realms=$userRealm
cacheManager=org.apache.shiro.cache.ehcache.EhCacheManager
cacheManager.cacheManagerConfigFile=classpath:shiro-ehcache.xml
securityManager.cacheManager=$cacheManager
userRealm. cachingEnabled: Enable cache, default false;
userRealm. authenticationCachingEnabled: Enable authentication cache, that is, cache AuthenticationInfo information, default false;
userRealm.authenticationCacheName: Cache name of AuthenticationInfo information;
userRealm. authorizationCachingEnabled: Enable authorization cache, that is, cache AuthorizationInfo information, default false;
userRealm. authorizationCacheName: Cache name for AuthorizationInfo information;
cacheManager: Cache manager, EhCacheManager, Ehcache implementation, need to import the corresponding Ehcache dependencies, please refer to pom.xml;
Due to test cases, CacheManager of Ehcache needs to be changed to use VM singleton mode:
this.manager = new net.sf.ehcache.CacheManager(getCacheManagerConfigFileInputStream());
Instead of
this.manager = net.sf.ehcache.CacheManager.create(getCacheManagerConfigFileInputStream());
The test case
Java code
@Test
public void testClearCachedAuthenticationInfo() {
login(u1.getUsername(), password);
userService.changePassword(u1.getId(), password + "1");
RealmSecurityManager securityManager =
(RealmSecurityManager) SecurityUtils.getSecurityManager();
UserRealm userRealm = (UserRealm) securityManager.getRealms().iterator().next();
userRealm.clearCachedAuthenticationInfo(subject().getPrincipals());
login(u1.getUsername(), password + "1");
}
First, the login is successful (the corresponding AuthenticationInfo will be cached at this time), and then the password will be changed. The password changes; Then you need to call the clearCachedAuthenticationInfo method of Realm to clear the previously cached AuthenticationInfo. Otherwise, the next time you log in, you will get the same AuthenticationInfo as before you changed your password.
Java code
@Test
public void testClearCachedAuthorizationInfo() {
login(u1.getUsername(), password);
subject().checkRole(r1.getRole());
userService.correlationRoles(u1.getId(), r2.getId());
RealmSecurityManager securityManager =
(RealmSecurityManager) SecurityUtils.getSecurityManager();
UserRealm userRealm = (UserRealm)securityManager.getRealms().iterator().next();
userRealm.clearCachedAuthorizationInfo(subject().getPrincipals());
subject().checkRole(r2.getRole());
}
Similar to the previous use case; Call Realm's clearCachedAuthorizationInfo here to clear the previously cached AuthorizationInfo;
There is also clearCache, which calls both clearCachedAuthenticationInfo and clearCachedAuthorizationInfo, emptying both AuthenticationInfo and AuthorizationInfo.
UserRealm also provides clearAllCachedAuthorizationInfo, clearAllCachedAuthenticationInfo, clearAllCache for clearing the entire cache.
In some cases, this may not be the best choice. Consider discarding Shiro's cache directly and implementing your own cache through AOP. For reference:
https://github.com/zhangkaitao/es/tree/master/web/src/main/java/com/sishuok/es/extra/aop
In addition, when integrating with Spring, it can be considered to directly use Cache abstraction of Spring. SpringCacheManagerWrapper can be used to package Spring Cache and convert it to CacheManager implementation of Shiro:
https://github.com/zhangkaitao/es/blob/master/web/src/main/java/org/apache/shiro/cache/spring/SpringCacheManagerWrapper.java
Session cache
When we set CacheManager of SecurityManager, such as:
Java code
securityManager.cacheManager=$cacheManager
When we set SessionManager:
Java code
sessionManager=org.apache.shiro.session.mgt.DefaultSessionManager
securityManager.sessionManager=$sessionManager
If securityManager implements SessionsSecurityManager, it will automatically determine whether SessionManager implements the CacheManagerAware interface and set CacheManager to it if it does. sessionManager then determines whether the corresponding sessionDAO (for example, inherited from CachingSessionDAO) implements CacheManagerAware and sets CacheManager to it if it does. MySessionDAO in Chapter 9 is SessionDAO with cache; It will check the cache first and the database only if it cannot be found.
For CachingSessionDAO, the name of the cache can be set using the following configuration:
Java code
public interface CacheManager {
// Gets by the cache name 1 a Cache
public <K, V> Cache<K, V> getCache(String name) throws CacheException;
}
0
conclusion