SpringBoot进阶之整合Shiro实现缓存和会话管理
SpringBoot进阶之整合Shiro鉴权框架(五)前言
大家好,一直以来我都本着用最通俗的话理解核心的知识点, 我认为所有的难点都离不开 「基础知识」 的铺垫。目前正在出一个SpringBoot 长期系列教程,从入门到进阶, 篇幅会较多~ 适合人群学完Java基础 想通过Java快速构建web应用程序 想学习或了解SpringBoot SpringBoot进阶学习
「大佬可以绕过 ~」 背景
如果你是一路看过来的,很高兴你能够耐心看完。之前带大家学了 Springboot 基础部分,对基本的使用有了初步的认识, 接下来的几期内容将会带大家进阶使用,会先讲解基础中间件 的使用和一些场景的应用,或许这些技术你听说过,没看过也没关系,我会带大家一步一步的入门,耐心看完你一定会有收获 ~ 情景回顾
上期带大家学习了 Shiro 中如何进行权限认证,本期将带大家学习Shiro 中如何进行缓存和会话管理 ,最后我们将做一个在线用户管理以及强制下线用户的功能,同样的,我们集成到Springboot 中。 缓存集成
首先我们要明白使用缓存的原因,为啥要用它 还记得之前带大家实现的 用户认证 和权限认证 吗,那里我使用了MockUser ,真实场景中是要去数据查询的,这样一来就会产生耗时,请求多的时候数据库肯定忙不过来了,所以我们需要使用缓存来提高程序响应速度
缓存使用 Redis ,下面就带大家整一下: org.crazycake shiro-redis 2.4.2.1-RELEASE
修改 ShiroConfig ,添加方法 public RedisManager redisManager() { RedisManager redisManager = new RedisManager(); return redisManager; } public RedisCacheManager cacheManager() { RedisCacheManager redisCacheManager = new RedisCacheManager(); redisCacheManager.setRedisManager(redisManager()); return redisCacheManager; } @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm()); securityManager.setRememberMeManager(rememberMeManager()); // 添加缓存 securityManager.setCacheManager(cacheManager()); return securityManager; }
这样就可以了,大家可以把测试获取用户的地方改成数据库获取,看下 控制台 sql日志会明显减少,因为有一部分是从缓存拿的 Session会话管理
这部分功能还是比较好玩的,学完可以自由发挥做一个房间功能,可以加入可以踢人,下面我们就开整 添加SessionDao
修改 ShiroConfig ,添加方法,因为我们使用的是Redis 缓存 @Bean public RedisSessionDAO sessionDAO() { RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); redisSessionDAO.setRedisManager(redisManager()); return redisSessionDAO; } @Bean public SessionManager sessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); Collection listeners = new ArrayList(); listeners.add(new ShiroSessionListener()); sessionManager.setSessionListeners(listeners); sessionManager.setSessionDAO(sessionDAO()); return sessionManager; }
实现 SessionListener public class ShiroSessionListener implements SessionListener { // 原子值,可以维护用户数 private final AtomicInteger sessionCount = new AtomicInteger(0); // 建立时 @Override public void onStart(Session session) { sessionCount.incrementAndGet(); } // 停止时 @Override public void onStop(Session session) { sessionCount.decrementAndGet(); } // 过期时 @Override public void onExpiration(Session session) { sessionCount.decrementAndGet(); } }
最后同样的,想要开启需要我们注入到 Manager 中: @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm()); securityManager.setRememberMeManager(rememberMeManager()); securityManager.setCacheManager(cacheManager()); // 注入session manager securityManager.setSessionManager(sessionManager()); return securityManager; } 获取在线用户
我们先定义一个类,用来记录在线用户: @Data public class UserOnline implements Serializable { private static final long serialVersionUID = 3828664348416633856L; private String sessionId; private String userId; private String username; private String host; private String ip; private String status; private Date startTime; private Date lastTime; private Long timeout; }
那么怎么获取呢?我们定义一个方法,大家实践中可以抽到 Service 层,这里方便演示,我直接写到控制器里 @RestController public class IndexController { @Autowired private SessionDAO sessionDAO; @RequiresPermissions("p:user") @RequestMapping("/index") public String index(Model model) { // 登录成后,即可通过Subject获取登录的用户信息 User user = (User) SecurityUtils.getSubject().getPrincipal(); model.addAttribute("user", user); return "index --->" + user.getUsername(); } @RequiresPermissions("p:admin") @RequestMapping("/userOnline/list") @ResponseBody public List list() { List list = new ArrayList<>(); Collection sessions = sessionDAO.getActiveSessions(); for (Session session : sessions) { UserOnline userOnline = new UserOnline(); User user = new User(); SimplePrincipalCollection principalCollection; if (session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null) { continue; } else { principalCollection = (SimplePrincipalCollection) session .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); user = (User) principalCollection.getPrimaryPrincipal(); userOnline.setUsername(user.getUsername()); userOnline.setUserId(user.getId().toString()); } userOnline.setSessionId((String) session.getId()); userOnline.setHost(session.getHost()); userOnline.setStartTime(session.getStartTimestamp()); userOnline.setLastTime(session.getLastAccessTime()); Long timeout = session.getTimeout(); if (timeout == 0l) { userOnline.setStatus("离线"); } else { userOnline.setStatus("在线"); } userOnline.setTimeout(timeout); list.add(userOnline); } return list; } } 强制用户下线
如果你看谁不爽,可以直接让他下线,hhh~ @RequiresPermissions("p:admin") @RequestMapping("/forceLogout") @ResponseBody public boolean forceLogout(String sessionId) { Session session = sessionDAO.readSession(sessionId); session.setTimeout(0); return true; }
是不是很简单,这里就不演示了,大家自行试试 结束语
本期内容就到这里结束了,总结一下,本节主要讲了 Shiro 如何进行缓存以及如何进行用户会话管理,大家可以举一反三,做一些小功能尝试尝试 下期预告
下期给大家讲讲 Shiro 中如何整合JWT ,这个大家应该不陌生,如果不知道啥是JWT 也没关系,我会带大家一步一步入门,下期也是Shiro 系列的终极篇,内容可能有点多,耐心看完哦。欢迎加群一起学习交流 ~ 往期内容我的博客(阅读体验较佳) Springboot入门 Springboot基础(一) Springboot基础(二) Springboot基础(三) Springboot基础(四) Springboot基础(五) SpringBoot进阶之缓存中间件Redis SpringBoot进阶之MyBatis分页插件 SpringBoot进阶之跨域问题处理(CORS) SpringBoot进阶之日志集成 SpringBoot进阶之请求拦截 SpringBoot进阶之事务管理及并发问题 SpringBoot进阶之整合Shiro鉴权框架(一) SpringBoot进阶之整合Shiro鉴权框架(二) SpringBoot进阶之整合Shiro鉴权框架(三) SpringBoot进阶之整合Shiro鉴权框架(四) 项目源码(源码已更新 欢迎star )springboot-all 地址 : https://github.com/qiuChengleiy/springboot-all.git
为什么阿里赔钱也要做88VIP会员?年轻人的体面,是从付费会员开始的。早在几年前,就有人这样调侃。今年,山姆会员Costco会员到底值不值这样的话题,又把会员这一身份推上了热搜。在双11这样的购物节,会员卡同样是备受
大家预测一下,柳传志还能打赢联想保卫战吗?保卫战?首先,要厘清楚保什么战?保超高薪资?保超高退休金?还是保股改的成果?司马南哪一处说错了?养着法务部门,告他不就完了?这么一家国际化世界500强企业,何须躲躲闪闪?所以,说明
降噪耳机不支持通话降噪?降噪耳机,顾名思义,应该是在使用耳机听音乐接听电话等过程中,能够有效降低噪音干扰,给人一个安静舒适的收听环境。实际情况却并非如此。近期,四川消费网接到投诉咨询,消费者反映花费近20
由司马南手撕联想看国有资产的流失最近网络大咖司马南,在网络上发布了7期视频,都是关于联想的,质疑联想由纯国有企业,逐步由人为因素逐步转变为私人企业。联想集团最初确实由中科院出资成立,企业化后逐步由各种持股平台,将
魅族pro5屏幕清晰吗?你好,我在2015年12月份买的Pro5用了一年多了,我谈谈这款手机的感受1。硬件参数pro5搭载5。7英寸的三星superamoled19201080的屏幕,号称与S6一样优秀三
联想集团这回要完了吗?联想完不完不知道。但这个所谓的教父柳传志及其女儿巳经完了。哪怕他有再多的资产,几代十几代人花不完,但人格人设彻底完了,成了人人喊打的过街老鼠,活着比死了还难受。司马老师手撕联想内幕
小米手机现在还能买吗?我觉得小米手机确实是不能买了,不光是小米,三星华为也都不能买了,不是因为头条上所呈现的各种断流翻车发热电衰等毛病,而是因为安卓手机已经没啥技术含量了,买个两千多的红米或真我就足够应
联想一年利润38亿,杨元庆年薪1。7亿多不多?问题是他的工资应该由谁来给定?严查联想高管!苹果公司2020年9月27日到21年9月25日,公司净利润946。8亿美元,库克年薪2。65亿美元,占净利润的0。27989。杨元庆一个
比特早报IBM研制迄今最大超导量子计算机,德州仪器欲建12英寸晶圆制造厂2021年11月18日消息,昨夜今晨,科技圈都发生了哪些大事?行业大咖抛出了哪些新的观点?比特网为您带来值得关注的科技资讯最强超导量子计算机上新IBM公司宣称,其已经研制出了一台能
联想真的会沉默吗?如果司马南说的毫无根据,大家想一想联想有专职的法律顾问,大批管理人员,会在第一时间内就做出快速反应。我更相信是司马南提出的问题大多数是事实,提的太突然,不知如何是好。就像教父所说,
联想充其量是个走下坡路的暴发户最近网上司马南与联想大战,说什么的都有,不加赘述。大家回想自己身边的爆发户从成功到幕落过程。发迹赶上时代发展的春风和自己超强的能力,快速完成原始积累(肯定有游走于法律边缘的原罪),