shiro学习(一)

来源:互联网 发布:数据冗余分类 编辑:程序博客网 时间:2024/06/05 20:39

1、关于shiro的Realm权限执行原理的理解:
1.1、继承AuthorizingRealm定义自己的Realm,realm里面的doGetAuthenticationInfo(AuthenticationToken token)方法是在登录时候做验证,根据token获取用户提交的用户名,然后到数据库查找是否存在该用户,存在则new一个SimpleAuthenticationInfo对象,然后交由给CredentialsMatcher的doCredentialsMatch方法,去匹配密码是否一致。
1.2、当访问有权限限制的url或资源的时候,会调用doGetAuthorizationInfo(PrincipalCollection principals),该方法也是返回一个预先设置好了role、permission的SimpleAuthorizationInfo,然后判断当前访问的资源需要的权限,是否在SimpleAuthorizationInfo里面。在每次访问有权限的资源(加了@RequiresPermissions,或者url在shiroFilter的filterChainDefinitions里面,有role,perm的资源,如user/* = role[user],user/*=perm[user:*])的时候都会调用,所以可以考虑将realm里面的授权信息放在缓存里面,避免每次访问数据库。

2、授权信息配置在缓存中:
配合ehcache使用,spring-shiro.xml:

    <bean id="myRealm" class="com.sz.pos.shiro.realm.MyRealm">        <property name="credentialsMatcher" ref="credentialsMatcher" />        <property name="cachingEnabled" value="false" />        <!-- 如需要自定义缓存时间放开以下.修改 ehcache.xml -->        <property name="authenticationCachingEnabled" value="true" />        <property name="authenticationCacheName" value="authenticationCache" />        <property name="authorizationCachingEnabled" value="true" />        <property name="authorizationCacheName" value="authorizationCache" />    </bean>    <!-- shiro缓存管理器 -->    <bean id="cacheManager" class="com.sz.pos.shiro.spring.SpringCacheManagerWrapper">        <property name="cacheManager" ref="springCacheManager" />    </bean>    <bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">        <property name="cacheManager" ref="ehcacheManager" />    </bean>    <!--ehcache -->    <bean id="ehcacheManager"        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">        <property name="configLocation" value="classpath:config/ehcache.xml" />    </bean>
ehcache.xml增加如下配置:
<cache name="authorizationCache" maxEntriesLocalHeap="2000"        eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0"        overflowToDisk="false" statistics="true">    </cache>    <cache name="authenticationCache" maxEntriesLocalHeap="2000"        eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0"        overflowToDisk="false" statistics="true">    </cache>

编写实现了CacheManager接口的SpringCacheManagerWrapper类:

import java.util.ArrayList;import java.util.Collection;import java.util.Collections;import java.util.HashSet;import java.util.List;import java.util.Set;import org.apache.shiro.cache.Cache;import org.apache.shiro.cache.CacheException;import org.apache.shiro.cache.CacheManager;import org.apache.shiro.util.CollectionUtils;import org.springframework.cache.support.SimpleValueWrapper;import net.sf.ehcache.Ehcache;public class SpringCacheManagerWrapper implements CacheManager {    private org.springframework.cache.CacheManager cacheManager;    /**     * 设置spring cache manager     *     * @param cacheManager     */    public void setCacheManager(org.springframework.cache.CacheManager cacheManager) {        this.cacheManager = cacheManager;    }    public <K, V> Cache<K, V> getCache(String name) throws CacheException {        org.springframework.cache.Cache springCache = cacheManager.getCache(name);        return new SpringCacheWrapper(springCache);    }    static class SpringCacheWrapper implements Cache {        private org.springframework.cache.Cache springCache;        SpringCacheWrapper(org.springframework.cache.Cache springCache) {            this.springCache = springCache;        }        public Object get(Object key) throws CacheException {            Object value = springCache.get(key);            if (value instanceof SimpleValueWrapper) {                return ((SimpleValueWrapper) value).get();            }            return value;        }        public Object put(Object key, Object value) throws CacheException {            springCache.put(key, value);            return value;        }        public Object remove(Object key) throws CacheException {            springCache.evict(key);            return null;        }        public void clear() throws CacheException {            springCache.clear();        }        public int size() {            if (springCache.getNativeCache() instanceof Ehcache) {                Ehcache ehcache = (Ehcache) springCache.getNativeCache();                return ehcache.getSize();            }            throw new UnsupportedOperationException("invoke spring cache abstract size method not supported");        }        public Set keys() {            if (springCache.getNativeCache() instanceof Ehcache) {                Ehcache ehcache = (Ehcache) springCache.getNativeCache();                return new HashSet(ehcache.getKeys());            }            throw new UnsupportedOperationException("invoke spring cache abstract keys method not supported");        }        public Collection values() {            if (springCache.getNativeCache() instanceof Ehcache) {                Ehcache ehcache = (Ehcache) springCache.getNativeCache();                List keys = ehcache.getKeys();                if (!CollectionUtils.isEmpty(keys)) {                    List values = new ArrayList(keys.size());                    for (Object key : keys) {                        Object value = get(key);                        if (value != null) {                            values.add(value);                        }                    }                    return Collections.unmodifiableList(values);                } else {                    return Collections.emptyList();                }            }            throw new UnsupportedOperationException("invoke spring cache abstract values method not supported");        }    }}
0 0