shiro学习(一)

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值