shrio redis实现集群模式下的session共享
shrio用redis实现sesion共享就是告诉redis用session对比cookie的时候不从本地内存拿,从redis拿,里面有session,sessionid等
直接用拿出的sessionid和cookie对比
思路:(对比前一篇的配置用途)
增加sessionmanager到securitymanager即可
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionValidationSchedulerEnabled" value="false" />
<property name="sessionDAO" ref="sessionDAO" />
<property name="sessionFactory" ref="sessionFactoryshr"/>
<property name="globalSessionTimeout" value="60000" />
<property name="sessionIdCookie">
<bean class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg name="name" value="SHRIOSESSIONID"/>
</bean>
</property>
<property name="sessionListeners">
<list>
<bean class="com.common.shrio.ShiroSessionListener"/>
</list>
</property>
</bean>
<bean id="sessionDAO" class="com.common.shrio.RedisSessionDao">
</bean>
<!--<bean name="sessionFactory" class="org.apache.shiro.session.mgt.SessionFactory"/>-->
<bean id="sessionFactoryshr" class="com.common.shrio.ShiroSessionFactory"/>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="sessionManager" ref="sessionManager" />
<property name="realm" ref="shiroDbRealm" />
</bean>
RedisSessionDao:
redis操作类
ShiroSessionFactory:
session配套
ShiroSessionListener:
退出清理等
第二:
在做shrio,session共享的同时shrio中的用户信息等也许做redis的存储,这个就需要用客户端cookie的信息作为key,存,之后可以确保之后客户端也可用cookie中的
key从redis拿到用户信息,session信息,不可直接用shrio中拿用户信息
登录成功的时候就保存cookie到客户端:
private void saveCurUserCookie(HttpServletRequest request, HttpServletResponse response)
{
String username = (String)request.getSession().getAttribute(
"ACEGI_SECURITY_LAST_USERNAME");
String ccidExtno = (String)request.getSession().getAttribute("EXTNO");
this.userDetailsSessionService.setExtNo(ccidExtno);
String ccid = "";
String extno = "";
if (ccidExtno.indexOf("_") > 0)
{
ccid = ccidExtno.substring(0, ccidExtno.indexOf("_"));
extno = ccidExtno.substring(ccidExtno.indexOf("_") + 1, ccidExtno
.length());
}
else {
extno = ccidExtno;
}
Cookie[] cookies = request.getCookies();
if (!"".equals(ccid)) {
String c_ccid = getCookieValue(cookies, "callcenterid");
if ((c_ccid == null) || (!extno.equals(c_ccid))) {
Cookie baseCookie = new Cookie("callcenterid", ccid);
baseCookie.setMaxAge(5184000);
response.addCookie(baseCookie);
}
}
String c_extension = getCookieValue(cookies, "extension");
if ((c_extension == null) || (!extno.equals(c_extension))) {
Cookie baseCookie = new Cookie("extension", extno);
baseCookie.setMaxAge(5184000);
response.addCookie(baseCookie);
}
String c_username = getCookieValue(cookies, "username");
if ((c_username == null) || (!username.equals(c_username))) {
Cookie baseCookie = new Cookie("username", username);
baseCookie.setMaxAge(5184000);
response.addCookie(baseCookie);
}
}
//获取cookie
private static String getCookieValue(Cookie[] cookies, String cookieName)
{
if (cookies == null) {
return null;
}
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookieName.equals(cookie.getName())) {
return cookie.getValue();
}
}
return null;
}
从request中拿到cookie,之后用这个作为key存取redis
HttpServletRequest request1 =(HttpServletRequest) ((WebSubject)SecurityUtils.getSubject()).getServletRequest(); //ServletActionContext.getRequest();
HttpServletResponse response1 =(HttpServletResponse) ((WebSubject)SecurityUtils.getSubject()).getServletResponse(); //ServletActionContext.getRequest();
//HttpServletRequest request2 =(HttpServletRequest) request1;
//HttpServletRequest request = ServletActionContext.getRequest();
//Map request3 = (Map)ActionContext.getContext().get("request");
Cookie[] cookies = request1.getCookies();
String username=getCookieValue(cookies, "username");
WebSession webSession=WebSessionManager.getInstance().getSession(username);
if(webSession==null){
webSession=WebSessionManager.getInstance().createSession(username);
}
if(value instanceof UserDetails ){
UserDetailsBean shiroUser = (UserDetailsBean) value;
webSession.setAttribute(username, value);
webSession.getAttribute(username);
}
HttpServletRequest request1 =(HttpServletRequest) ((WebSubject)SecurityUtils.getSubject()).getServletRequest();
Cookie[] cookies = request1.getCookies();
String username=getCookieValue(cookies, "username");
WebSession webSession= WebSessionManager.getInstance().getSession(username);
UserDetailsBean shiroUser = (UserDetailsBean) webSession.getAttribute(username);
注意
MyAuthenticationFilter中onLoginSuccess中的session.stop();需要注掉,否则用框架的登陆走了onLoginSuccess然后又清了session会报错
参考:
http://sgq0085.iteye.com/blog/2170405
相关推荐
"Spring Boot + Shiro + Redis 实现 Session 共享方案二" 1. 概述 本文档旨在介绍如何使用 Spring Boot、Shiro 和 Redis 实现分布式 session 共享,以解决 Web 应用程序的登录 session 统一问题。 2. 相关依赖 ...
在Redis集群模式下,数据会根据哈希槽(hash slot)进行分布,每个节点负责一部分槽,从而实现数据的自动分片。对于Shiro而言,这意味着需要一个能够理解这种分布式架构并能正确处理节点间通信的连接器。 org....
这种配置下,Spring Boot项目能够方便地利用Shiro与Redis配合,实现session数据的持久化和跨服务器共享。 首先,我们需要了解Apache Shiro如何处理session。在默认情况下,Shiro将session信息存储在内存中,但这种...
Spring Boot 整合 Redis 实现 Shiro 的分布式 Session 共享 Shiro 是一个优秀的 Java 安全框架,提供了强大的身份验证、授权和会话管理功能。然而,在分布式架构中,Shiro 的会话管理机制需要进行特殊处理,以便...
Shiro结合Redis
`shiro-redisson` 提供的基于 Redis 的会话管理,可以将会话数据存储在 Redis 中,实现会话在集群中的共享,确保用户在任何节点上都能保持会话状态。 4. **配置与集成** 要使用 `shiro-redisson`,首先需要在 ...
将SpringBoot、Shiro和Redis整合,主要目的是利用Shiro进行用户认证和授权,而Redis作为Session的共享存储,解决分布式环境下的会话一致性问题。以下是整合步骤: 1. **引入依赖**:在SpringBoot的pom.xml文件中...
本文将深入探讨如何在Spring MVC框架下实现Shiro与Redis集群的整合。 一、Shiro核心概念 1. 认证:验证用户身份的过程,确保用户是他们声称的人。 2. 授权:确定用户是否有权限执行特定操作。 3. 会话管理:跟踪...
为实现Web应用的分布式集群部署,要解决登录session的统一。本文利用shiro做权限控制,redis做session存储,结合spring boot快速配置实现session共享。
7. **Shiro-Redis**:Shiro-Redis2.9是Shiro的一个扩展,它将session数据存储在Redis缓存中,解决了在分布式环境下的session共享问题。Redis是一个高性能的键值数据库,具有丰富的数据结构支持,适合存储session这样...
Nginx+Tomcat+Redis实现session共享,通过Nginx作为前端的负载,把请求分发到后端的Tomcat服务器上,提高并发数;但是单纯的通过Nginx的ip_hash负载是很多问题的。只要用户一切换网络或者后端Tomcat主机宕机session就...
在SSM+Shiro架构中,Redis可以用来存储用户的Session信息,实现分布式会话管理,尤其在集群环境下,确保用户在不同服务器之间切换时仍能保持登录状态。此外,Redis还可以用于缓存Shiro的权限信息,提高权限查询速度...
1. **会话管理**: 通过Shiro的SessionManager,配置为使用Redis作为session的存储,实现分布式会话,解决集群环境下的session共享问题。 2. **权限缓存**: 将Shiro的权限信息缓存在Redis中,提高权限验证效率,同时...
- 默认情况下,Shiro的Session是基于内存的,无法在多服务器环境下共享。集成Redis后,Shiro将Session持久化到Redis,实现集群环境下的Session共享。 7. **DAO层自动生成插件**: - 这个项目集成了一个DAO层代码...
在这个名为"shiro-redis-session-master"的项目中,开发者采用Redis作为Shiro的会话管理存储,以实现跨服务器的集群会话共享,从而提高系统的可扩展性和可用性。 **一、Shiro框架** Shiro框架的核心组件包括...
Redis 的高可用性和高性能特性使得它成为 Shiro 在集群环境下的理想缓存解决方案。在实际应用中,你可能还需要结合其他技术,如 Spring Boot 或者 Dubbo,来更好地整合 Shiro 和 Redis,实现完整的安全和缓存管理。
3. **Session共享**:通过`RedisSessionDAO`,我们可以将Shiro的session数据存储到Redis中,实现分布式session。这样,用户在集群中的任意一台服务器登录后,其他服务器都能识别该用户。 **Mybatis集成** 1. **...
在微服务中我们一般采用的是无状态登录,而传统的session方式,在前后端分离的微服务架构下,如继续使用则必将要解决跨域sessionId问题、集群session共享问题等等。这显然是费力不讨好的,而整合shiro,却很不...
5. 安全会话管理:Shiro 提供了基于 Redis 的 SessionManager,可以设置 `cacheManager` 为 RedisCacheManager,这样 Shiro 的权限控制信息也可以存储在 Redis 中,实现权限缓存。 通过以上步骤,Shiro 就能利用 ...