springboot配置shiro多项目实现session共享的详细步骤

springboot配置shiro多项目实现session共享的详细步骤

公司需要这样的需求:

有两个项目master 主项目、suiteone 项目,两个项目各自由shiro 安全框架管理,当不能登录时,都无法访问,但当登录了其中一个,再访问另一个的时候不再需要登录即可访问。
如果想看为什么需要共享session ,可以去看我这篇文章。[shiro框架—关于多项目之间验证为什么需要共享session]

关于实现多项目共享session的逻辑介绍

其实在上边的链接里我已经说明了,但是怕大家不去看,所以我就又复制到了这里:
先来说一下我的理解 ,如下:

这里写图片描述
上图中master 项目为主项目,登录页即在这个项目中,suiteonesuitetwo 为两个从项目,当两个从项目有请求时,如果没有登录的时候,都会打到master 项目的登录页上。共享session 采用的是redis 存储。

上图的步骤如下:

  1. 浏览器请求master 项目,第一次请求的时候,也是会带着浏览器中的cookie 去请求,当然第一次去redis 里肯定找不到对应的session,会通过⑤进入到登录页。
  2. 当在登录页输入完正确的账号密码后,才能登录成功,否则仍会回到⑤。
  3. 在这一步的时候,会将登录成功后的session ,根据它,将生成sessionId串 ,并传到前端浏览器中,浏览器以cookie 存储。
  4. 同时将第③步中生成的session 存储到redis 中。
  5. 当前这里,不只是当登录失败的时候,会进入到登录页中,当浏览器长时间没有访问后台(每次浏览器访问后台,其实都会刷新session 的过期时间expireTime),导致session 超过时,也会进入到该步中。
  6. 当浏览器请求suiteonesuteTwo 这两个从项目时,肯定也是将当前浏览器中的所有的cookie 设置到request headers 请求头中。
  7. 根据传入的sessionId串 到共享的redis 存储中匹配。
  8. 如果匹配不到,则会跳转到master 项目的登录页,如果匹配成功,则会访问通过。

以上描述的并不难,大家也都会想到,那么如何将扯了这么多的淡 真正更简单的,落地实现才是大家关注的。

多项目通过redis共享session的步骤

1、shiro 共享session 的切入点,下图是shiro的验证流程

这里写图片描述

2、配置过程

说一下实现shiro 项目共享session 的配置步骤:

(1)项目多添加redis 依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-redis</artifactId><version>1.3.6.RELEASE</version></dependency>
(2)配置application.properties 文件
###主项目写成自己项目的登录页面路径,从项目必须写完整的主项目登录页面url
shiro.loginUrl=/login
###主从项目的下边名字必须一致
shiro.jessionid=sessionId
###redis连接配置
spring.redis.host=192.168.1.160
spring.redis.port=6379
spring.redis.password=znxd
(3)重写session 增删改查,与redis接入
package microservice.sc.shiro;import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.Collection;
import java.util.concurrent.TimeUnit;@Service
public class RedisSessionDao extends AbstractSessionDAO {// Session超时时间,单位为毫秒private long expireTime = 120000;@Autowiredprivate RedisTemplate redisTemplate;// Redis操作类,对这个使用不熟悉的,可以参考前面的博客public RedisSessionDao() {super();}public RedisSessionDao(long expireTime, RedisTemplate redisTemplate) {super();this.expireTime = expireTime;this.redisTemplate = redisTemplate;}@Override // 更新sessionpublic void update(Session session) throws UnknownSessionException {System.out.println("===============update================");if (session == null || session.getId() == null) {return;}session.setTimeout(expireTime);redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.MILLISECONDS);}@Override // 删除sessionpublic void delete(Session session) {System.out.println("===============delete================");if (null == session) {return;}redisTemplate.opsForValue().getOperations().delete(session.getId());}@Override
// 获取活跃的session,可以用来统计在线人数,如果要实现这个功能,可以在将session加入redis时指定一个session前缀,统计的时候则使用keys("session-prefix*")的方式来模糊查找redis中所有的session集合public Collection<Session> getActiveSessions() {System.out.println("==============getActiveSessions=================");return redisTemplate.keys("*");}@Override// 加入sessionprotected Serializable doCreate(Session session) {System.out.println("===============doCreate================");Serializable sessionId = this.generateSessionId(session);this.assignSessionId(session, sessionId);redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.MILLISECONDS);return sessionId;}@Override// 读取sessionprotected Session doReadSession(Serializable sessionId) {System.out.println("==============doReadSession=================");if (sessionId == null) {return null;}return (Session) redisTemplate.opsForValue().get(sessionId);}public long getExpireTime() {return expireTime;}public void setExpireTime(long expireTime) {this.expireTime = expireTime;}public RedisTemplate getRedisTemplate() {return redisTemplate;}public void setRedisTemplate(RedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}
}
(4)将重写的RedisSessionDao 接入到shiro 中的sessionManager
@Beanpublic RedisSessionDao getRedisSessionDao(){return new RedisSessionDao();}/*** @see DefaultWebSessionManager* @return*/@Bean(name="sessionManager")public DefaultWebSessionManager defaultWebSessionManager() {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();//sessionManager.setCacheManager(cacheManager());sessionManager.setGlobalSessionTimeout(43200000); //12小时sessionManager.setDeleteInvalidSessions(true);//关键在这里sessionManager.setSessionDAO(getRedisSessionDao());sessionManager.setSessionValidationSchedulerEnabled(true);sessionManager.setDeleteInvalidSessions(true);sessionManager.setSessionIdCookie(getSessionIdCookie());return sessionManager;}
(5)将sessionManager 注入到securityManager
     /*** @see org.apache.shiro.mgt.SecurityManager* @return*/@Bean(name="securityManager")public DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager manager = new DefaultWebSecurityManager();manager.setRealm(userRealm());//manager.setCacheManager(cacheManager());manager.setSessionManager(defaultWebSessionManager());return manager;}
(6)设置登录页的地址cookie名字

首先引入我们刚才application.properties文件中的内容:

@Value("${shiro.loginUrl}")
private String masterLoginUrl;@Value("${shiro.jessionid}")
private String jessionId;

然后注入到配置中:

	@Bean(name = "shiroFilter")public ShiroFilterFactoryBean shiroFilter(){ShiroFilterFactoryBean bean = new MShiroFilterFactoryBean(); //指向自定义过滤器,自定义过滤器对js/css等忽略bean.setSecurityManager(securityManager());//在这里设置登录页bean.setLoginUrl(masterLoginUrl);Map<String, Filter>filters = new LinkedHashMap<>();filters.put("anon", new AnonymousFilter());bean.setFilters(filters);//shiro配置过滤规则少量的话可以用hashMap,数量多了要用LinkedHashMap,保证有序,原因未知Map<String, String> chains =  new LinkedHashMap<>();chains.put("/login","anon");chains.put("/loginForm","anon");chains.put("/**", "authc");bean.setFilterChainDefinitionMap(chains);return bean;}
	 /*** 给shiro的sessionId默认的JSSESSIONID名字改掉* @return*/@Bean(name="sessionIdCookie")public SimpleCookie getSessionIdCookie(){SimpleCookie simpleCookie = new SimpleCookie(jessionId);return simpleCookie;}

注意,如果值注入不进来,则看一下当前的shiro 配置文件里的LifecycleBeanPostProcessor 的注入是否为static 方法,如下:

/*** 该类如果不设置为static,@Value注解就无效,原因未知* @return*/@Beanpublic static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}
(7)测试

我的项目如下:
如下图所示,我们是springboot+dubbo+zookeeper 的项目:
这里写图片描述
分别启动30000端口 的主项目master 项目、300001端口的从项目suiteone 项目,启动后,

  • 首先访问主项目http://localhost:30000肯定进入登录页。
  • 当再访问http://localhost:30001/test ,因为没有登录直接被重定向到http://localhost:30000 的登录页上,即主项目的登录页。
  • 当在当前登录页上登录成功后,再次访问http://localhost:30001/test ,该接口即返回了数值。
  • 当我在主项目的http://localhost:30000中退出登录,再次访问http://localhost:30001/test ,同样重定向了登录页。
  • 应该能确定实现了session 共享。

具体如下图:
登录页面,在这时访问30001 也会进入下边这个页面:
这里写图片描述
登录成功后:
这里写图片描述
登录成功后访问30001的接口,即可以访问成功
这里写图片描述

配置完成,如有问题请及时留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556690.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shiro框架---关于多项目之间验证为什么需要共享session

关于多项目之间登录验证为什么需要共享session 服务器上部署了两个项目&#xff0c;登录之后才可以访问其中的接口。现在想要实现&#xff0c;当登录项目1成功后&#xff0c;可以不需要再登录项目2&#xff0c;直接可以访问项目2中的接口。 大部分人都会想到&#xff0c;共享s…

怎么黑学校计算机室的电脑,大学计算机室变身黑网吧 校方:有需求

河南经贸职业学院计算机房在课间向学生收费办卡使用&#xff0c;被指变相开设“网吧”&#xff0c;一些学生痴迷于网络游戏中。对此&#xff0c;校方向记者表示&#xff1a;“上课时间不收费&#xff0c;课外时间有偿使用&#xff0c;学生有上网需求。”计算机房向学生收费玩游…

Linux重置Mysql密码_解决MySQL for Linux错误 ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost

Linux重置Mysql密码 一般这个错误是由密码错误引起&#xff0c;解决的办法自然就是重置密码。 假设我们使用的是root账户。 1.重置密码的第一步就是跳过MySQL的密码认证过程&#xff0c;方法如下&#xff1a; #vim /etc/my.cnf(注&#xff1a;windows下修改的是my.ini) 在…

excel 公式 平移 引用单元格_不学会这3个Excel隔列求和函数公式,你只能一个个单元格去相加...

Excel中的求和&#xff0c;并不是你们想的123那么简单。有单条件求和、多条件求和&#xff0c;合并单元格求和&#xff0c;隔列求和等等。有关求和的函数也很多&#xff0c;例如SUM函数、SUMIFS函数、还有与这两个函数结合使用的其它函数等等&#xff0c;不知道你们了解了多少。…

Linux - 查看软件安装与安装路径

【1】查看软件是否安装 因为linux安装软件的方式比较多&#xff0c;所以没有一个通用的办法能查到某些软件是否安装了。总结起来就是这样几类&#xff1a; ① rpm包安装的&#xff0c;可以用rpm -qa看到&#xff0c;如果要查找某软件包是否安装&#xff0c;用 rpm -qa | grep…

计算机mips是什么,在计算机术语中,什么叫MIPS

2006-08-18在计算机术语中,什么叫VGA显卡所处理的信息最终都要输出到显示器上&#xff0c;显卡的输出接口就是电脑与显示器之间的桥梁&#xff0c;它负责向显示器输出相应的图像信号。CRT显示器因为设计制造上的原因&#xff0c;只能接受模拟信号输入&#xff0c;这就需要显卡能…

springboot配置多项目下统一切换不同环境变量profile办法

springboot配置多项目下统一切换不同环境变量profile办法 springboot 适合于微服务那种多项目开发&#xff0c;每一个小项目就是一个springboot 项目&#xff0c;比如我们这样&#xff1a; 问题发生&#xff1a; 我们知道springboot 项目中的配置文件application.propertie…

springboot 关于 Class path contains multiple SLF4J bindings.警告的解决

springboot 关于 Class path contains multiple SLF4J bindings.警告的解决 有一次配置好springboot项目启动后&#xff0c;忽然发现有下边的警告&#xff1a; SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/E:/mavenJarOnline/c…

c# 计算机ip,C# 获取电脑的IP,网关,MAC,计算机名。。

【实例简介】【实例截图】【核心代码】using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Net;using System.Net.Sockets;us…

wxml 判断 小程序_如何判断小程序外包公司是否靠谱

微信小程序依附微信App&#xff0c;由于其无需下载&#xff0c;无需安装&#xff0c;无需注册&#xff0c;直接用微信授权登录&#xff0c;不占内存等优势在短短2年多的时间斩获超过10亿用户。又因为微信官方开通了小程序附近五公里展示以及在微信搜一搜增加“小程序”搜索选项…

make *** 没有指明目标并且找不到 makefile。 停止。_Makefile目标文件搜索(VPATH和vpath)...

我们都知道一个工程文件中的源文件有很多&#xff0c;并且存放的位置可能不相同(工程中的文件会被放到不同的目录下)&#xff0c;所以按照之前的方式去编写 Makefile 会有问题。我们之前列举的例子&#xff0c;所有的源文件基本上都是存放在与 Makefile 相同的目录下。只要依赖…

电脑设置访问苹果服务器未响应,苹果连接电脑没反应,教您苹果连接电脑没反应怎么解决...

但只要是电子设备&#xff0c;那就一定会出现问题&#xff0c;所以苹果手机也不能例外。不过小编我有想好解决的方法&#xff0c;并且我已经将解决苹果手机连接电脑没反应的方法写在了文章的后面&#xff0c;小伙伴们往下看即可。苹果手机作为手机品牌界的翘楚&#xff0c;它一…

Linux下netstat命令详解

一、介绍 Netstat是控制台命令,是一个监控TCP/IP网络的非常有用的工具&#xff0c;它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据&#xff0c;一般用于检验本机各端口的网络连接情况。 二、输出…

hbase可视化工具_做数据可视化,三大热门BI工具试用总结

什么BI分析工具好用&#xff1f;今天通过3款BI产品Power BI、FineBI、亿信ABI为范例&#xff0c;进行对比分析。一、产品背景Power BI是微软的&#xff0c;14年15年开始初见苗头&#xff0c;之前主要是基于Excel的高级功能&#xff0c;包括Power Query&#xff0c;Power Pivot&…

IDEA Translation插件安装及设置鼠标悬浮提示的自动翻译

1、安装插件 Translation 2.设置鼠标悬浮提示 3.在代码界面鼠标悬停在方法上 就会自动翻译提示

在虚拟机中ftp服务器的配置,ftp服务器在虚拟机中配置文件

ftp服务器在虚拟机中配置文件 内容精选换一换由于主机中 /etc/ssh/sshd_config 配置文件中对服务器与客户端交互的活动心跳时间做出了限制&#xff0c;所以在一个ansible任务中如果在“规定时间”中主机没有任何响应则ssh服务断开(注&#xff1a;上述“规定时间”是指在/etc/ss…

@PostConstruct注解详解

简介 javaEE5引入了PostConstruct和PreDestroy两个作用于Servlet生命周期的注解&#xff0c;实现Bean初始化之前和销毁之前的自定义操作 使用场景 在项目中主要是在Servlet初始化之前加载一些缓存数据等 API使用说明 PostConstruct 注释用于在依赖关系注入完成之后需要执行…

用户密码到底要怎样存储?

作为互联网公司的信息安全从业人员经常要处理撞库扫号事件&#xff0c;产生撞库扫号的根本原因是一些企业发生了信息泄露事件&#xff0c;且这些泄露数据未加密或者加密方式比较弱&#xff0c;导致黑客可以还原出原始的用户密码。 目前已经曝光的信息泄露事件至少上百起&#…

dateframe取某列数据_Python获取时序数据并进行可视化分析

更多精彩&#xff0c;请点击上方蓝字关注我们&#xff01;1. 准备工作tushare是一个第三方财经数据接口包&#xff0c;需要安装包并完成注册。安装tushare包pip install tushare 为防恶意调用接口数据&#xff0c;官方()需要新用户完成注册、提高积分(例如达到200)、取得访问权…

Shiro 登录认证源码详解

Apache Shiro 是一个强大且灵活的 Java 开源安全框架&#xff0c;拥有登录认证、授权管理、企业级会话管理和加密等功能&#xff0c;相比 Spring Security 来说要更加的简单。 本文主要介绍 Shiro 的登录认证&#xff08;Authentication&#xff09;功能&#xff0c;主要从 Sh…