前言

在 shiro 中每次去拦截请求进行权限认证的时候,都会去数据库查询该用户的所有权限信息, 这个时候就是有一个问题了,因为用户的权限信息在短时间内是不可变的,每次查询出来的数据其实都是重复数据,没必要每次都去重新获取这个数据,统一放在缓存中进行管理,这个时候,我们只需要获取一次权限信息,存入到缓存中,待缓存过期后,再次重新获取即可。

例如,我执行一个查询多次,它执行多次权限查询。

使用 Reids 缓存

加入 shiro-redis 依赖

<!-- shiro-redis -->
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>2.4.2.1-RELEASE</version>
</dependency>

配置 Redis

和前面系统配置 Reids 一样。

1. 在系统配置文件中加入 Redis 配置参数:

spring:
redis:
host: 192.168.19.200 # host ,默认 localhost
port: 6379 # 端口号,默认6379
pool:
# 设置都是默认值,可以按需求设计
max-active: 8 # 可用连接实例的最大数目,默认值为8;如果赋值为-1,则表示不限制;
max-idle: 8 # 控制一个pool最多有多少个状态为idle(空闲的)的redis实例,默认值也是8。
max-wait: -1 # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。
min-idle: 0 # 控制一个pool最少有多少个状态为idle(空闲的)的redis实例,默认值为0。
timeout: 0 # 连接超时时间 单位 ms,默认为0
password: master # 密码,根据自己的 redis 设计,默认为空
  1. 这个我们是要使用 RedisManager 管理我们的 Redis,它默认没有注入我们设置的这些参数,需要我们自己手动创建一个注入我们设置的参数。
@ConfigurationProperties(prefix = "spring.redis")
public class CustomRedisManager extends RedisManager { }

配置 Shiro 缓存

    /**
* redis 管理
*/
@Bean
public CustomRedisManager customRedisManager() {
return new CustomRedisManager();
} /**
* redis 缓存
*/
@Bean
public RedisCacheManager cacheManager(CustomRedisManager redisManager) {
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager);
return redisCacheManager;
} @Bean
public SecurityManager securityManager(OAuth2Realm oAuth2Realm, SessionManager sessionManager, RedisCacheManager cacheManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 可以添加多个认证,执行顺序是有影响的
securityManager.setRealm(oAuth2Realm);
securityManager.setSessionManager(sessionManager);
// 注册 缓存
securityManager.setCacheManager(cacheManager);
return securityManager;
}

使用测试

我们加入缓存后,看是个什么情况:

执行多次请求,只执行了一次查询权限的 SQL。

可以去 redis-cli 查看 keys,检查是否存在权限对象的 key。

使用 Ehcache 缓存

加入依赖

<!-- shiro ehcache -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.3.2</version>
</dependency>
<!-- ehchache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>

Ehcache 配置

新增一个 Ehcache 配置文件 shiro-ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir/Tmp_EhCache" />
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120" /> <!-- 登录记录缓存锁定1小时 -->
<cache
name="passwordRetryCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true" />
</ehcache>

配置 EhCache 缓存

    /**
* EhCache 缓存
*/
@Bean
public EhCacheManager ehCacheManager() {
EhCacheManager em = new EhCacheManager();
em.setCacheManagerConfigFile("classpath:config/shiro-ehcache.xml");
return em;
} @Bean
public SecurityManager securityManager(OAuth2Realm oAuth2Realm, SessionManager sessionManager,
RedisCacheManager cacheManager, EhCacheManager ehCacheManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 可以添加多个认证,执行顺序是有影响的
securityManager.setRealm(oAuth2Realm);
securityManager.setSessionManager(sessionManager);
// 设置缓存
securityManager.setCacheManager(ehCacheManager);
return securityManager;
}

参考文章

学习Spring Boot:(十九)Shiro 中使用缓存的更多相关文章

  1. spring Boot(十九):使用Spring Boot Actuator监控应用

    spring Boot(十九):使用Spring Boot Actuator监控应用 微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台 ...

  2. spring boot(十四)shiro登录认证与权限管理

    这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...

  3. (转)Spring Boot (十九):使用 Spring Boot Actuator 监控应用

    http://www.ityouknow.com/springboot/2018/02/06/spring-boot-actuator.html 微服务的特点决定了功能模块的部署是分布式的,大部分功能 ...

  4. 学习Spring Boot:(二十六)使用 RabbitMQ 消息队列

    前言 前面学习了 RabbitMQ 基础,现在主要记录下学习 Spring Boot 整合 RabbitMQ ,调用它的 API ,以及中间使用的相关功能的记录. 相关的可以去我的博客/RabbitM ...

  5. 学习Spring Boot:(二十五)使用 Redis 实现数据缓存

    前言 由于 Ehcache 存在于单个 java 程序的进程中,无法满足多个程序分布式的情况,需要将多个服务器的缓存集中起来进行管理,需要一个缓存的寄存器,这里使用的是 Redis. 正文 当应用程序 ...

  6. 学习 Spring Boot 知识看这一篇就够了

    从2016年因为工作原因开始研究 Spring Boot ,先后写了很多关于 Spring Boot 的文章,发表在技术社区.我的博客和我的公号内.粗略的统计了一下总共的文章加起来大概有六十多篇了,其 ...

  7. (转)Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理

    http://www.ityouknow.com/springboot/2017/06/26/spring-boot-shiro.html 这篇文章我们来学习如何使用 Spring Boot 集成 A ...

  8. Spring Boot(十四):spring boot整合shiro-登录认证和权限管理

    Spring Boot(十四):spring boot整合shiro-登录认证和权限管理 使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉 ...

  9. Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理

    这篇文章我们来学习如何使用 Spring Boot 集成 Apache Shiro .安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在 Java 领域一般有 Spring S ...

随机推荐

  1. RocEDU.课程设计2018 第六组 第三周进展 博客补交

    RocEDU.课程设计2018第六组 第三周进展 博客补交 小组成员:20155211解雪莹,20155217杨笛,20155227辜彦霖 计划完成任务:完成课设所有内容 实际完成任务:跑通老师uco ...

  2. Python中类和对象在内存中是如何保存?

    类以及类中的方法在内存中只有一份,而根据类创建的每一个对象都在内存中需要存一份,大致如下图: 如上图所示,根据类创建对象时,对象中除了封装 name 和 age 的值之外,还会保存一个类对象指针,该值 ...

  3. Spring Boot(十一):Spring Boot 中 MongoDB 的使用

    MongoDB 是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多.由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配 ...

  4. 01.如何把.py文件打包成为exe,重点讲解pyinstaller的用法

    1.应用场景 1.1 故事背景 我自己用python写了一个小程序发给其他同事用,给他的就是一个.py文件,不过他觉得比较麻烦,还要安装环境,他问我有没有简单一点的方式,我给一个exe文件,他就不用安 ...

  5. BugkuCTF web2

    前言 写了这么久的web题,算是把它基础部分都刷完了一遍,以下的几天将持续更新BugkuCTF WEB部分的题解,为了不影响阅读,所以每道题的题解都以单独一篇文章的形式发表,感谢大家一直以来的支持和理 ...

  6. 冒泡排序算法的C++,Java和Python实现和冒泡排序算法三种语言效率的比较

    冒泡排序原理: 这一篇百度经验讲得很好,我不多说了 https://jingyan.baidu.com/article/6525d4b13f920bac7d2e9484.html 他讲的是C语言,没有 ...

  7. 验证Xpath和CSS 路径是否有效

    XPath定位和CSS定位在Selenium中是经常使用的. 在FireFox浏览器和Chrome浏览器,可以使用这样的方法来验证定位是否准确. 以Chrome浏览器做范例 按键盘的F12 进入开发者 ...

  8. PAT甲题题解-1007. Maximum Subsequence Sum (25)-求最大子区间和

    题意:给出n个数,求最大连续的子区间和,并且输出该区间的第一个和最后一个数. 如果所有数都小于0,那么则输出0,第一个数和最后一个数. 看数据k的范围,就知道肯定不能两层for循环来求区间和,O(n^ ...

  9. 《Linux内核分析》课程第二周学习总结

    姓名:何伟钦 学号:20135223 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  10. 更新pip10后 ImportError: cannot import name ‘main'

    百度了几个回答都没有解决问题,有些回答明显是直接复制过来的一点价值都没有,然后google一下立马解决.很多时候不能怪搜索引擎,问题出在一些国内网友对知识的不负责任 解决:找到报错文件,也就是那个pi ...