SpringBoot + Shiro 缓存&记住密码

x33g5p2x  于2021-12-01 转载在 Spring  
字(4.7k)|赞(0)|评价(0)|浏览(268)

一般来讲,记住密码的基本处理,就是把用户的一些基本信息(密码)存入浏览器的Cookie,下次登录的时候优先验证Cookie,后端做处理;以此来实现记住密码的功能!使用shiro自带的RememberMe功能,使用起来比较简单,只需简单的配置。

需注意一点的是,网站如果对安全性要求比较高的,一般都不建议有记住密码的功能! 因为Cookie是保存在本机电脑浏览器里,不排除其他用户能使用此电脑,拷走Cookie,导入其他电脑继续使用您的账号登录!

shiro实现了身份验证和权限验证。但是,如果我们登录之后多次访问http://localhost:8080/userInfo/userDel的话,会发现权限验证会每次都执行一次。这是有问题的,因为像用户的权限这些我们提供给shiro一次就够了。

下面,我们开始给shiro添加缓存支持:

1.添加依赖
<!-- shiro ehcache -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.2.2</version>
        </dependency>

        <!-- 包含支持UI模版(Velocity,FreeMarker,JasperReports), 邮件服务, 脚本服务(JRuby), 缓存Cache(EHCache), 任务计划Scheduling(uartz)。 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
2.注入缓存

com.example.demo.config.Shiro.ShiroConfiguration中添加以下方法。

@Bean
    public EhCacheManager ehCacheManager() {
        System.out.println("ShiroConfiguration.getEhCacheManager()");
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManagerConfigFile("classpath:config/ehcache-shiro.xml");
        return ehCacheManager;
    }

将缓存对象注入到SecurityManager中:

@Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setCacheManager(ehCacheManager()); //注入缓存对象。
        return securityManager;
    }
3.添加配置文件

在src/main/resouces/config中添加ehcache-shiro.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="es">

    <diskStore path="java.io.tmpdir"/>

    <!-- name:缓存名称。 maxElementsInMemory:缓存最大数目 maxElementsOnDisk:硬盘最大缓存个数。 eternal:对象是否永久有效,一但设置了,timeout将不起作用。 overflowToDisk:是否保存到磁盘,当系统当机时 timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 clearOnFlush:内存数量最大时是否清除。 memoryStoreEvictionPolicy: Ehcache的三种清空策略; FIFO,first in first out,这个是大家最熟的,先进先出。 LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。 LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。 -->
    <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" />

    <!-- 登录记录缓存锁定10分钟 -->
    <cache name="passwordRetryCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true">
    </cache>

</ehcache>

启动项目,再多次访问http://localhost:8080/userInfo/userDel,这时候只会在后台打印一次配置权限的信息了,说明shiro缓存起了作用。

---------------------下面我们开始配置记住密码-----------

1.在com.example.demo.config.Shiro.ShiroConfiguration中加入下面两个方法:
//cookie对象;
    @Bean
    public SimpleCookie rememberMeCookie() {
        System.out.println("ShiroConfiguration.rememberMeCookie()");
        //这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");

        //<!-- 记住我cookie生效时间30天 ,单位秒;-->
        simpleCookie.setMaxAge(259200);
        return simpleCookie;
    }

    //cookie管理对象;
    @Bean
    public CookieRememberMeManager cookieRememberMeManager() {
        System.out.println("ShiroConfiguration.rememberMeManager()");
        CookieRememberMeManager manager = new CookieRememberMeManager();
        manager.setCookie(rememberMeCookie());
        return manager;
    }

将rememberMeManager注入到SecurityManager中

@Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setCacheManager(ehCacheManager());
        securityManager.setRememberMeManager(cookieRememberMeManager()); //注入rememberMeManager;
        return securityManager;
    }

ShiroFilterFactoryBean中添加记住我过滤器user,添加user过滤器的资源在记住我或认证之后就可以直接访问了。

Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
...
        filterChainDefinitionMap.put("/index", "user");
        filterChainDefinitionMap.put("/", "user");
....

最后,在login.html页面添加记住我单选框

<P><input type="checkbox" name="rememberMe" />记住我</P>

启动项目,正常登录后关闭浏览器,再打开浏览器输入http://localhost:8080/index,这时候就可以直接访问index页面,不需要再登录了。

相关文章

微信公众号

最新文章

更多