Spring Security(07)——缓存UserDetails

 Spring Security provides a UserDetailsService implementation class that can cache UserDetails, CachingUserDetailsService. The construction of this class receives a UserDetailsService implementation class for actually loading UserDetails. When UserDetails needs to be loaded, it will first be obtained from the cache. If there is no corresponding UserDetails in the cache, it will be loaded using the UserDetailsService implementation class held, and then the loaded result will be stored in the cache. The interaction between UserDetails and the cache is implemented through the UserCache interface. The CachingUserDetailsService by default has a reference to a null implementation of UserCache, NullUserCache. Following is the class definition for 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;

    }

}

       We can see that when the corresponding UserDetails does not exist in the cache, the referenced UserDetailsService type delegate will be used for loading. After loading, store it in the Cache and return it. In addition to NullUserCache, Spring Security also provides us with an Ehcache-based UserCache implementation class, EhCacheBasedUserCache, whose source code is as follows.

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;

    }

}

 

       From the above source code, we can see that the Ehcache referenced by EhCacheBasedUserCache is empty, so when we need to cache UserDetails, we only need to define an Ehcache instance and inject it into EhCacheBasedUserCache. Next let's look at an example of defining a CachingUserDetailsService that supports caching UserDetails.

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

      <!--  Use CachingUserDetailsService which can cache UserDetails -->

      <security:authentication-provider

         user-service-ref="cachingUserDetailsService" />

   </security:authentication-manager>

   <!--  UserDetailsService that can cache UserDetails -->

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

      <!--  UserDetailsService that actually loads UserDetails -->

      <constructor-arg ref="userDetailsService"/>

      <!--  UserCache that caches UserDetails -->

      <property name="userCache">

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

            <!--  Ehcache object for real caching  -->

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

         </bean>

      </property>

   </bean>

   <!--  An Ehcache object named ehcache4UserDetails will be created using the default CacheManager  -->

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

   <!--  UserDetailsService that loads UserDetails from the database -->

   <bean id="userDetailsService"

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

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

   </bean>

 

       In the above configuration, the Ehcache bean object defined by EhcacheFactoryBean adopts the default configuration, which will use the default CacheManager, that is, directly obtain the currently existing CacheManager object through CacheManager.getInstance(), if it does not exist, use the default configuration Automatically create one, of course, this can specify the CacheManager we need to use through the cacheManager property, and the CacheManager can be defined through EhCacheManagerFactoryBean. In addition, if the name of the corresponding cache is not specified, the beanName will be used by default, which is ehcache4UserDetails in the above configuration , which can be specified through the cacheName property. In addition, the cached configuration information is also used by default. For more information on Spring's use of Ehcache, please refer to my other article " Spring Using Cache ".

 

(Note: This article is written based on Spring Security 3.1.6)

 

 (Note: Original article, please indicate the source for reprinting. Original address: http://haohaoxuexi.iteye.com/blog/2159871 )

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324908937&siteId=291194637