共计 4137 个字符,预计需要花费 11 分钟才能阅读完成。
我的公众号:MarkerHub,Java 网站:https://markerhub.com
更多精选文章请点击:Java 笔记大全.md
小 Hub 领读:
集群的分布式场景中,咱们须要把泛滥服务的会话状态保持一致,常见的就是把会话信息保留到 redis 中实现共享,那么你晓得 shiro 集成 redis 实现会话共享有多简略吗?真的只须要 4 步!
在一些分布式场景中,比方一个简略负载平衡场景,一个 nginx,反向代理到两个 tomcat,tomcat 运行这同样的我的项目,那么这时候,服务的会话须要共享,因为咱们曾经应用了 shiro 来实现咱们的认证受权逻辑,那么 shiro 实现登录之后,如何让另外一个服务同时也是登录状态呢?
咱们延用上篇文章的我的项目代码,应用两个端口 8080、8081 别离启动我的项目。
- http://localhost:8080
- http://localhost:8081
有些同学不晓得怎么用 idea 同一个我的项目别离启动两个端口,其实很简略,只须要在 Run/Debug Configurations
的VM options
上,指定启动端口 -Dserver.port=8081
即可!
ok,别离启动 8080 和 8081 我的项目之后,登录 8080 我的项目,而后拜访 8081,发现 8081 未登录!图示如下:
那么,如何能力 8080 登录之后,8081 也同时实现登录呢?
非凡解决形式
其实在负载平衡集群中,有些人是这样解决问题,给 ip 指定服务,比方某个用户申请通过 nginx 反向代理到 8080 服务,那么 nginx 上指定ip_hash: 根据 ip 调配形式
,那么这个用户就始终拜访同一个服务,不会拜访到 8081 服务,所以用户就始终是拜访对立服务,所以在用户看来,他就始终是登录状态的。
然而,这是有缺点的,因为 ip 和服务绑定了,退出这个服务挂了之后,是不会转发到其余服务,所以对这用户来说,就拜访异样。
所以咱们须要应用更罕用的负载平衡策略,比方轮询、权重等。
回顾 shiro 的架构与组件
ok,进入正题,shiro 做会话共享,会话信息能够存储到内存,数据库,或者缓存中间件中,这里咱们应用一个罕用的缓存中间件 Redis 来保留咱们的会话信息,那么,咱们就须要 shiro 集成 redis。
能够回顾一下之前咱们介绍过的 shiro 的整体架构:
下面与会话或缓存相干的组件有:
- Session Manager 会话管理器
- Session DAO 会话 DAO,将 session 保留到数据库、缓存等
- Cache Manager 缓存管理器,权限认证的缓存、用户及权限信息的缓存等
如果只是做会话共享,只是改写 Session DAO 如同也是能够的,我之前试过,不过既然 shiro 曾经集成 redis,那么数据啥的最好也一起共享吧,防止出现缓存不统一的状况。依照这个逻辑,其实就是重写这 3 个组件就行了。
shiro-redis 整合步骤
那么,有什么曾经写好的 shiro 集成 redis 整合我的项目嘛?
这里给大家介绍一个
https://github.com/alexxiyang/shiro-redis/
# 文档
https://github.com/alexxiyang/shiro-redis/blob/master/docs/README.md
# 或者
http://alexxiyang.github.io/shiro-redis/
readme.md 上有具体的教程,这里咱们间接应用 Spring boot starter
形式,因为须要写的代码少,间接写写配置就好。
第一步:导入 shiro-redis 的 starter 包
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis-spring-boot-starter</artifactId>
<version>3.2.1</version>
</dependency>
能够看下 shiro-redis-spring-boot-starter
源码:
能够看出,曾经蕴含了 shiro-spring-boot-web-starter
与shiro-redis
整合包了,所以之前我的项目中整合进来的 shiro-spring-boot-web-starter
能够正文掉了。
第二步,依据阐明,readme 外面说,如果你没有自定义创立 SessionManager or SessionsSecurityManager,那么会主动给你创立,集成实现。然而咱们自定义了 realm,所以 SecurityManager 还是必须要自定义的。
- com.markerhub.config.ShiroConfig
@Configuration
public class ShiroConfig {
@Autowired
RedisSessionDAO redisSessionDAO;
@Autowired
RedisCacheManager redisCacheManager;
@Bean
AccountRealm accountRealm() {return new AccountRealm();
}
@Bean
public SessionManager sessionManager() {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
// inject redisSessionDAO
sessionManager.setSessionDAO(redisSessionDAO);
return sessionManager;
}
@Bean
public DefaultWebSecurityManager securityManager(AccountRealm accountRealm, SessionManager sessionManager) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(accountRealm);
//inject sessionManager
securityManager.setSessionManager(sessionManager);
// inject redisCacheManager
securityManager.setCacheManager(redisCacheManager);
return securityManager;
}
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
// logged in users with the 'admin' role
chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");
// logged in users with the 'document:read' permission
chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]");
chainDefinition.addPathDefinition("/login", "anon");
chainDefinition.addPathDefinition("/doLogin", "anon");
// all other paths require a logged in user
chainDefinition.addPathDefinition("/**", "authc");
return chainDefinition;
}
}
相比之前的配置,多了配置了个 SessionManager,而后对应配置中注入 sessionManager 和 redisCacheManager。如同我的项目就曾经能够运行啦。
登录胜利之后查看 redis 中的数据成果如下:
阐明咱们的会话信息曾经保留到 redis 中啦。而后咱们再换个端口 8081 启动我的项目,发现 8080 登录胜利之后,8081 服务也是登录胜利状态。
第三步、依据需要调整参数,能够在配置文件中调整的参数我贴出来:
- application.yml
shiro-redis:
enabled: true
redis-manager:
host: 127.0.0.1:6379
ok,shiro-redis 曾经整合结束,是不是挺简略的哈。
留神点
应用这个整合包,有个留神点,如果你应用了 spring-boot-devtools 作为主动热加载重启,那么主动重启后会报错,解决办法也简略,官网曾经给出了解决方案:
If you are using shiro-redis with spring-boot-devtools. Please add this line to resources/META-INF/spring-devtools.properties (Create it if there is no this file):
restart.include.shiro-redis=/shiro-[\w-\.]+jar
所以,第四步:只须要在 resources 新建一个文件夹 META-INF,而后新建文件 spring-devtools.properties,内容为:
restart.include.shiro-redis=/shiro-[\\w-\\.]+jar
成果如下:
结束语
好了,明天先讲到这里吧,shiro 系列的文章曾经发了几篇了,前面还有一篇集成单点登录的,而后就完结了哈。这里是 MarkerHub,我是小 Hub 吕一明,快去星标置顶我的公众号吧!
(完)
举荐浏览
Java 笔记大全.md
太赞了,这个 Java 网站,什么我的项目都有!https://markerhub.com
这个 B 站的 UP 主,讲的 java 真不错!