).用户通过浏览器直接访问服务器资源
).用户登录信息在单台机器上验证
[多台服务器登录验证]
).用户通过浏览器直接访问服务器资源
).用户登录信息在多台机器上验证登录信息
).此时需要共享服务器会话(如redis),所有服务器验证同一个会话
).会话ID,需要共享,在不同服务器之间(相同顶级域名可以共享
Cookie)
实现步骤
spring-shiro.xml 配置
<!-- cacheManager 指定缓存管理为Redis缓存管理,指定redis缓存前缀 -->
<bean id="cacheShrioManager" class="org.crazycake.shiro.RedisCacheManager"> <property name="redisManager" ref="redisShrioManager" /> <property name="keyPrefix" value="trader:shiro:cache:"/> </bean> <!-- shiro redisManager 用redis缓存管理,共享会话 --> <bean id="redisShrioManager" class="org.crazycake.shiro.RedisManager"> <property name="host" value="${redis.server.ip}"/> <property name="port" value="${redis.server.port}"/> <property name="expire" value="1800"/><!-- 30分钟--> </bean> <!-- sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID --> <bean id="shareSessionCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <!-- cookie的name,对应的默认是 JSESSIONID --> <constructor-arg name="name" value="jsID}" /> <!-- jsessionId的path为 / 用于多个系统共享jsessionId --> <property name="path" value="/" /> <!-- 会话超时时间,单位:秒 --> <property name="maxAge" value="36000" /> <!-- 30分钟--> <property name="httpOnly" value="true"/> <property name="domain" value="localhost"/><!-- 配置顶级域名--> </bean> <!-- 定义 Shiro 主要业务对象 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="sessionManager" ref="sessionManager" /> <property name="cacheManager" ref="cacheShrioManager" /> <property name="realm" ref="customizeAuthorizingRealm"/> </bean> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!-- 除特殊地址外,其它访问地址,都需要用户登录后,才可以访问 /** = user --> |
---|
自定义会话 SessionRedisDao
package com.fx.spring.shiro.session.dao; import com.fx.constant.SystemConstant; import com.fx.db.redis.service.RedisService; import com.fx.spring.shiro.session.util.SessionCacheUtil; import org.apache.shiro.session.Session; import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.io.Serializable; @Repository public class SessionRedisDao extends EnterpriseCacheSessionDAO { private final static String redis_session_id = SystemConstant.ONLINEUSER.ADMIN_ONLINEUSER_SESSION ; Logger logger = LoggerFactory.getLogger(SessionRedisDao.class) ; @Autowired RedisService redisService; // 创建session,保存到数据库 @Override protected Serializable doCreate(Session session) { Serializable sessionId = super.doCreate(session); redisService.set( redis_session_id + sessionId,session); redisService.expireCache(redis_session_id + sessionId, SessionCacheUtil.getSessionTimeoutMILLISECONDS()); logger.debug("[SessionRedisDao create session ] sessionId:{} session:{}", redis_session_id + sessionId,session); return sessionId; } @Override protected Session doReadSession(Serializable sessionId) { Session session =null; Object object = redisService.get( redis_session_id + sessionId); if(object !=null && object instanceof Session){ session = (Session)object; }else{ session = super.doReadSession(sessionId); } logger.debug("[SessionRedisDao read session ] sessionId:{} session:{}", redis_session_id + sessionId,session); return session; } // 更新session的最后一次访问时间 @Override protected void doUpdate(Session session) { try{ logger.debug("[SessionRedisDao update session ] sessionId:{} session:{}", redis_session_id + session.getId(),session); redisService.set( redis_session_id + session.getId(),session); redisService.expireCache(redis_session_id + session.getId(), SessionCacheUtil.getSessionTimeoutMILLISECONDS()); }catch (Exception e){ } } @Override protected void doDelete(Session session) { redisService.remove( redis_session_id + session.getId()); logger.debug("[SessionRedisDao delete session ] sessionId:{} session:{}", redis_session_id + session.getId(),session); } } |
---|