美文网首页
Shiro13-Shiro 整合开发-缓存

Shiro13-Shiro 整合开发-缓存

作者: 我相信你爱过gg | 来源:发表于2017-05-21 19:35 被阅读91次

    解决授权频繁查询数据库问题

    缓存流程

    shiro 中提供了认证信息和授权信息的缓存.
    注意: shiro 默认关闭认证信息缓存, 但是对于授权信息的缓存默认是开启的.

    用户认证通过.
    该用户第一次授权: 调用 realm 查询数据库.
    该用户第二次授权: 不调用 realm 查询数据库, 直接从缓存中取出授权信息(权限标识符).

    使用 ehcache

    在 spring-shiro.xim 中配置 cacheManager

    <!-- securityManager安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="customRealm" />
        <!-- 注入缓存管理器 -->
        <property name="cacheManager" ref="cacheManager"/>
    </bean>
    
    <!-- 缓存管理器 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
    </bean>
    

    创建shiro-ehcache.xml

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
        <!--diskStore:缓存数据持久化的目录 地址  -->
        <diskStore path="F:\develop\ehcache" />
        <defaultCache 
            <!-- 缓存最大个数 -->
            maxElementsInMemory="1000" 
            <!-- 硬盘最大缓存个数 -->
            maxElementsOnDisk="10000000"
            <!-- 对象是否永久有效,一但设置了,timeout将不起作用 -->
            eternal="false" 
            <!-- 当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中 -->
            overflowToDisk="false" 
            <!-- 是否缓存虚拟机重启期数据 -->
            diskPersistent="false"
            <!--
                设置对象在失效前的允许闲置时间(单位:秒)。
                仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大 
            -->
            timeToIdleSeconds="120"
            <!--
                设置对象在失效前允许存活时间(单位:秒)。
                最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
            -->
            timeToLiveSeconds="120" 
            <!-- 磁盘失效线程运行时间间隔,默认是120秒。 -->
            diskExpiryThreadIntervalSeconds="120"
            <!--
                当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)
                你可以设置为FIFO(先进先出)或是LFU(较少使用)
            -->
            memoryStoreEvictionPolicy="LRU">
        </defaultCache>
    </ehcache>
    

    缓存清空

    如果用户正常退出, 缓存自动清空.
    如果用户非正常退出, 缓存自动清空.

    如果我们修改了权限, 而且用户不退出系统, 修改的权限无法立即生效.
    那么如何在修改了权限之后立即生效呢?
    实现思路: 在权限修改后调用 realm 的 clearCached() 方法进行清除缓存.

    //清除缓存
    public void clearCached() {
        PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
        super.clearCache(principals);
    }
    

    验证码

    自定义FormAuthenticationFilter

    public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
    
        //原FormAuthenticationFilter的认证方法
        @Override
        protected boolean onAccessDenied(ServletRequest request,
                ServletResponse response) throws Exception {
            //在这里进行验证码的校验
            
            //从session获取正确验证码
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpSession session =httpServletRequest.getSession();
            //取出session的验证码(正确的验证码)
            String validateCode = (String) session.getAttribute("validateCode");
            
            //取出页面的验证码
            //输入的验证和session中的验证进行对比 
            String randomcode = httpServletRequest.getParameter("randomcode");
            if(randomcode!=null && validateCode!=null && !randomcode.equals(validateCode)){
                //如果校验失败,将验证码错误失败信息,通过shiroLoginFailure设置到request中
                httpServletRequest.setAttribute("shiroLoginFailure", "randomCodeError");
                //拒绝访问,不再校验账号和密码 
                return true; 
            }
            return super.onAccessDenied(request, response);
        }
    }
    

    ** 配置自定FormAuthenticationFilter **

    <!-- 自定义form认证过虑器 -->
    <!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
        <bean id="formAuthenticationFilter" 
        class="cn.itcast.ssm.shiro.CustomFormAuthenticationFilter ">
            <!-- 表单中账号的input名称 -->
            <property name="usernameParam" value="username" />
            <!-- 表单中密码的input名称 -->
            <property name="passwordParam" value="password" />
     </bean>
    
            <!-- 自定义filter配置 -->
            <property name="filters">
                <map>
                    <!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
                    <entry key="authc" value-ref="formAuthenticationFilter" />
                </map>
            </property>
    

    相关文章

      网友评论

          本文标题:Shiro13-Shiro 整合开发-缓存

          本文链接:https://www.haomeiwen.com/subject/nrdmxxtx.html