前言

前段时间做了一个图床的小项目,安全框架使用的是Shiro。为了使用户7x24小时访问,决定把项目由单机升级为集群部署架构。但是安全框架shiro只有单机存储的SessionDao,尽管Shrio有基于Ehcache-rmi的组播/广播实现,然而集群的分布往往是跨网段的,甚至是跨地域的,所以寻求新的方案。

架构

方案

使用 redis 集中存储,实现分布式集群共享用户信息,这里我们采用第三方开源插件crazycake来实现,pom.xml 引入:

[XML] 纯文本查看 复制代码
<dependency>    [/align][align=left]<groupId>org.springframework.boot</groupId>  [/align][align=left]  <artifactId>spring-boot-starter-data-redis</artifactId>[/align][align=left]</dependency>[/align][align=left]<dependency>   [/align][align=left] <groupId>org.crazycake</groupId>  [/align][align=left]  <artifactId>shiro-redis</artifactId> [/align][align=left]   <version>3.2.3</version>[/align][align=left]</dependecy>
配置 application.properties:
[PowerShell] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
9
# Redis# 数据库索引(默认为0)redis.database=0
# 服务器地址 变更为自己的
redis.host=127.0.0.1
# 服务器连接端口
redis.port=6379
# 服务器连接密码,如果不设置密码注释掉即可
# redis.password=
# 连接超时时间(毫秒)
redis.timeout=30000
本来crazycake插件已经实现了RedisManager,但是参数不可配,这里我们需要自己重写一下:
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
public class RedisManager extends WorkAloneRedisManager implements IRedisManager {   
private RedisProperties redis;  
 private JedisPool jedisPool;  
 public RedisManager(RedisProperties redis) {      
 this.redis = redis;    }   
private void init() {      
 synchronized(this) {         
  if (this.jedisPool == null) {               
this.jedisPool = new JedisPool(this.getJedisPoolConfig(), redis.getHost(), redis.getPort(),                       
redis.getTimeout(), redis.getPassword(), redis.getDatabase());           
}       
}   
}   
@Override  
 protected Jedis getJedis() {       
if (this.jedisPool == null) {          
 this.init();       
}       
return this.jedisPool.getResource();   
}}
参数配置 RedisProperties:
[Java] 纯文本查看 复制代码
@Data
@ConfigurationProperties(prefix = "redis")
public class RedisProperties {   
private String host;   
private int port;   
private int timeout;   
private String password;   
private int database;}
配置 ShiroConfig:
[Java] 纯文本查看 复制代码
/** * Shiro权限配置 * 一定要配置 @Configuration 和 @EnableConfigurationProperties 注解 */
@Configuration
@EnableConfigurationProperties({RedisProperties.class})
public class ShiroConfig {   
private RedisProperties redis;   
public ShiroConfig(RedisProperties redis) {       
this.redis = redis;   
}   
@Bean  
 public UserRealm userRealm() {       
return new UserRealm();   
}   
@Bean   
public ShiroFilterFactoryBean shiroFilterFactoryBean (SecurityManager securityManager) {
       ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/index.html");
       shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        // 拦截器
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
       /**
         * 静态文件
         */
       filterChainDefinitionMap.put("/file/**","anon");
        /**
         * 登录注册
         */
       filterChainDefinitionMap.put("/register.shtml","anon");
       filterChainDefinitionMap.put("/login.shtml","anon");
        /**
        * 管理后台
        */
       filterChainDefinitionMap.put("/sys/**", "roles[admin]");
       filterChainDefinitionMap.put("/**", "authc");
       shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
       return shiroFilterFactoryBean;
   }
    @Bean
    public SessionsSecurityManager securityManager() {
       DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm());
       securityManager.setCacheManager(cacheManager());
        securityManager.setSessionManager(sessionManager());
       return securityManager;
   }
   @Bean
    public DefaultWebSessionManager sessionManager() {
       DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
       sessionManager.setSessionIdUrlRewritingEnabled(false);
        sessionManager.setSessionDAO(redisSessionDAO());
       return sessionManager;
   }
    @Bean
   public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }
   /**
     * cacheManager 缓存 redis实现
     * @return
     */
    public RedisCacheManager cacheManager() {
       RedisCacheManager redisCacheManager = new RedisCacheManager();
       redisCacheManager.setRedisManager(redisManager());
        return redisCacheManager;
   }
    /**
    * 配置shiro redisManager
     * @return
     */
    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager(redis);
       return redisManager;
   }
    /**
    * RedisSessionDAO shiro sessionDao层的实现
    * 原理就是重写 AbstractSessionDAO
     * 有兴趣的小伙伴自行阅读源码
     */
   @Bean
    public RedisSessionDAO redisSessionDAO() {
       RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
       redisSessionDAO.setRedisManager(redisManager());
       return redisSessionDAO;
   }}

小结

是不是很爽,以后重启应用再也不用担心用户投诉了?
更多技术资讯可关注:itheimaGZ公冢号获取

SpringBoot:Shiro 整合 Redis的更多相关文章

  1. SpringBoot简单整合redis

    Jedis和Lettuce Lettuce 和 Jedis 的定位都是Redis的client,所以他们当然可以直接连接redis server. Jedis在实现上是直接连接的redis serve ...

  2. SpringBoot中整合Redis、Ehcache使用配置切换 并且整合到Shiro中

    在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...

  3. springboot+shiro整合教程

    进阶教程: 1. springboot+shiro+redis(单机redis版)整合教程 2. springboot+shiro+redis(集群redis版)整合教程 3.springboot+s ...

  4. springBoot(8)---整合redis

    Springboot整合redis 步骤讲解 1.第一步jar导入: <dependency> <groupId>org.springframework.boot</gr ...

  5. SpringBoot之整合Redis分析和实现-基于Spring Boot2.0.2版本

    背景介绍 公司最近的新项目在进行技术框架升级,基于的Spring Boot的版本是2.0.2,整合Redis数据库.网上基于2.X版本的整个Redis少之又少,中间踩了不少坑,特此把整合过程记录,以供 ...

  6. 【SpringBoot】整合Redis实战

    ========================9.SpringBoot2.x整合Redis实战 ================================ 1.分布式缓存Redis介绍 简介: ...

  7. Springboot + shiro 整合之Url拦截设置(转)

    shiro 整合到springboot 还是比较简单的,只需要新建一个spring-shiro.xml的配置文件: <span style="font-size:14px;" ...

  8. SpringBoot学习(七)—— springboot快速整合Redis

    目录 Redis缓存 简介 引入redis缓存 代码实战 Redis缓存 @ 简介 redis是一个高性能的key-value数据库 优势 性能强,适合高度的读写操作(读的速度是110000次/s,写 ...

  9. 完整SpringBoot Cache整合redis缓存(二)

    缓存注解概念 名称 解释 Cache 缓存接口,定义缓存操作.实现有:RedisCache.EhCacheCache.ConcurrentMapCache等 CacheManager 缓存管理器,管理 ...

  10. SpringBoot 2.x 开发案例之 Shiro 整合 Redis

    前言 前段时间做了一个图床的小项目,安全框架使用的是Shiro.为了使用户7x24小时访问,决定把项目由单机升级为集群部署架构.但是安全框架shiro只有单机存储的SessionDao,尽管Shrio ...

随机推荐

  1. SQL基础教程(第2版)第7章 集合运算:7-1 表的加减法

    第7章 集合运算:7-1 表的加减法 ● 集合运算就是对满足同一规则的记录进行的加减等四则运算.● 使用UNION(并集). INTERSECT(交集). EXCEPT(差集)等集合运算符来进行集合运 ...

  2. 自动化运维工具ansible中常用模块总结

    1.yum模块: name:要操作的软件包名字,可以是一个url或者本地rpm包路径,如name=nginx update_cache:更新软件包缓存,如update_cache=yes则更新软件包缓 ...

  3. IO读写

    1.read & write read: 把数据从内核缓冲区复制到进程缓冲区. write: 把数据从进程缓冲区复制到内核缓冲区. 上层程序的IO操作.不是物理设备级别的读写,而是缓存的复制. ...

  4. HDU-2544 最短路 Dijkstra模板题

    题目链接:https://vjudge.net/problem/HDU-2544 题意: 题目要求找到节点1到节点n之间的一条最短路 分析: Dijkstra模板题 单源最短路径,可以用dijkstr ...

  5. NOIp2018解题报告

    D1: T1 \(Ans = \sum_{i=2}^{n} |a_{i}-a_{i-1}|\),正确性可由贪心证得 T2 考虑贪心,选出一个属于A的集合,容易证明其是最优的 然后考虑一个数如果不被选, ...

  6. vue多选验证

    vue select 多选 验证 <FormItem :prop="'formList.'+index+'.name'" label="姓名" :rule ...

  7. 杂记 -- 关于less在vue项目中的使用

    1.安装less,less-loader npm install less less-loader --save 2.配置wepack.js(vue3+版本中不用自己设置) //添加less路径模块 ...

  8. spring获取当前动态代理对象

    由于spring中的aop拦截的是代理对象 当拦截的目标方法被本类的另一个方法调用时,会出现拦截失效 最佳实践: 例如拦截RegulationService的update(regulation)方法, ...

  9. [PHP防火墙]输入内容存在危险字符,安全起见,已被本站拦截

    之前在很多的网站都看到了360webscan的攻击拦截脚本,正好分析并学习一下. 下载地址:http ://webscan.360.cn/protect/down?domain = blog.dybo ...

  10. DB---WAL技术

    摘要:这个WAL技术也需要加以整理,即 write-ahead logging (预写式日志),待整理...