Spring Security Cache UserDetails

Spring Security Cache UserDetails

缓存 UserDetails

Spring Security 供给了一个实行了不妨缓存 UserDetails 的 UserDetailsService 实行类,CachingUserDetailsService。该类的结构接受一个用来真实加载 UserDetails 的 UserDetailsService 实行类。当须要加载 UserDetails 时,其开始会从缓存中获得,即使缓存中没有对应的 UserDetails 生存,则运用持有的 UserDetailsService 实行类举行加载,而后将加载后的截止寄存在缓存中。UserDetails 与缓存的交互是经过 UserCache 接口来实行的。CachingUserDetailsService 默许具有 UserCache 的一个空实行援用,NullUserCache。以次是 CachingUserDetailsService 的类设置。

public class CachingUserDetailsService implements UserDetailsService {

private UserCache userCache = new NullUserCache();

private final UserDetailsService delegate;

CachingUserDetailsService(UserDetailsService delegate) {

this.delegate = delegate;

}

public UserCache getUserCache() {

return userCache;

}

public void setUserCache(UserCache userCache) {

this.userCache = userCache;

}

public UserDetails loadUserByUsername(String username) {

UserDetails user = userCache.getUserFromCache(username);

if (user == null) {

user = delegate.loadUserByUsername(username);

}

Assert.notNull(user, "UserDetailsService" + delegate + "returned null for username" + username + "." +

"This is an interface contract violation");

userCache.putUserInCache(user);

return user;

}

}

咱们不妨看到当缓存中不生存对应的 UserDetails 时将运用援用的 UserDetailsService 典型的 delegate 举行加载。加载后再把它寄存到 Cache 中并举行归来。除去 NullUserCache 除外,Spring Security 还为咱们供给了一个鉴于 Ehcache 的 UserCache 实行类,EhCacheBasedUserCache,其源码如次所示。

public class EhCacheBasedUserCache implements UserCache, InitializingBean{

private static final Log logger = LogFactory.getLog(EhCacheBasedUserCache.class);

private Ehcache cache;

public void afterPropertiesSet() throws Exception {

Assert.notNull(cache, "cache mandatory");

}

public Ehcache getCache(){

returncache;

}

public UserDetails getUserFromCache(String username){

Element element = cache.get(username);

if (logger.isDebugEnabled()) {

logger.debug("Cache hit:" + (element != null) + "; username:" + username);

}

if (element == null) {

returnnull;

} else {

return (UserDetails) element.getValue();

}

}

public void putUserInCache(UserDetails user){

Element element = new Element(user.getUsername(), user);

if (logger.isDebugEnabled()) {

logger.debug("Cache put:" + element.getKey());

}

cache.put(element);

}

public void removeUserFromCache(UserDetails user){

if (logger.isDebugEnabled()) {

logger.debug("Cache remove:" + user.getUsername());

}

this.removeUserFromCache(user.getUsername());

}

public void removeUserFromCache(String username){

cache.remove(username);

}

public void setCache(Ehcache cache){

this.cache = cache;

}

}

从上述源码咱们不妨看到 EhCacheBasedUserCache 所援用的 Ehcache 是空的,以是,当咱们须要对 UserDetails 举行缓存时,咱们只须要设置一个 Ehcache 范例,而后把它注入给 EhCacheBasedUserCache 就不妨了。接下来咱们来看一下设置一个扶助缓存 UserDetails 的 CachingUserDetailsService 的示例。

<security:authentication-manager alias="authenticationManager">

<!-- 运用不妨缓存 UserDetails 的 CachingUserDetailsService -->

<security:authentication-provider

user-service-ref="cachingUserDetailsService" />

</security:authentication-manager>

<!-- 不妨缓存 UserDetails 的 UserDetailsService -->

<bean id="cachingUserDetailsService" class="org.springframework.security.config.authentication.CachingUserDetailsService">

<!-- 真实加载 UserDetails 的 UserDetailsService -->

<constructor-arg ref="userDetailsService"/>

<!-- 缓存 UserDetails 的 UserCache -->

<property name="userCache">

<bean class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">

<!-- 用来真实缓存的 Ehcache 东西 -->

<property name="cache" ref="ehcache4UserDetails"/>

</bean>

</property>

</bean>

<!-- 将运用默许的 CacheManager 创造一个名为 ehcache4UserDetails 的 Ehcache 东西 -->

<bean id="ehcache4UserDetails" class="org.springframework.cache.ehcache.EhCacheFactoryBean"/>

<!-- 从数据库加载 UserDetails 的 UserDetailsService -->

<bean id="userDetailsService"

class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">

<property name="dataSource" ref="dataSource" />

</bean>

在上头的摆设中,咱们经过 EhcacheFactoryBean 设置的 Ehcache bean 东西沿用的是默许摆设,其将运用默许的 CacheManager,即径直经过 CacheManager.getInstance() 获得暂时仍旧生存的 CacheManager 东西,如不生存则运用默许摆设机动创造一个,固然这不妨经过 cacheManager 属性指定咱们须要运用的 CacheManager,CacheManager 不妨经过 EhCacheManagerFactoryBean 举行设置。其余,即使没有指定对应缓存的称呼,默许将运用 beanName,在上述摆设中即为 ehcache4UserDetails,不妨经过 cacheName 属性举行指定。其余,缓存的摆设消息也都是运用的默许的。

分享到 :
相关推荐

Leave a Reply

Your email address will not be published. Required fields are marked *