shiro redis session共享

来源:互联网 发布:上海医保报销软件 编辑:程序博客网 时间:2024/05/22 07:59

有个后端项目需要添加一台服务器做均衡。框架用到了springMvc,shiro作为登录和权限控制,发现用spring-session做session有点问题,具体不在描 参考作者忘记了-.-!

   1.application.xml  shiro配置

<bean id="collectionRedisSessionDao" class="com.fh.dao.CollectionRedisSessionDao"></bean><!-- session管理器 -->      <bean id="sessionManager"          class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">          <!-- 超时时间 -->          <property name="globalSessionTimeout" value="7200000" />          <!-- session存储的实现 -->          <property name="sessionDAO" ref="collectionRedisSessionDao"></property>         <!-- sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID  -->          <property name="sessionIdCookie" ref="sharesession" />         <!-- 定时检查失效的session -->          <property name="sessionValidationSchedulerEnabled" value="true" />      </bean>       <bean id="sharesession" class="org.apache.shiro.web.servlet.SimpleCookie">        <!-- cookie的name,对应的默认是 JSESSIONID -->        <constructor-arg name="name" value="SHAREJSESSIONID"/>        <!-- jsessionId的path为 / 用于多个系统共享jsessionId -->        <property name="path" value="/"/>    </bean><!-- ================ Shiro start ================ --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="ShiroRealm" /><property name="sessionManager" ref="sessionManager"></property>     </bean>
<!-- 項目自定义的Realm -->    <bean id="ShiroRealm" class="com.fh.interceptor.shiro.ShiroRealm" ></bean><!-- Shiro Filter --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager" /><property name="loginUrl" value="/" /><property name="successUrl" value="/main/index" /><property name="unauthorizedUrl" value="/login_toLogin" /><property name="filterChainDefinitions"><value>/static/login/** = anon/static/**         = anon/plugins/**     = anon/static/js/** = anon/uploadFiles/uploadImgs/** = anon/upload/**                 = anon           /code.do = anon           /login_login = anon           /app**/** = anon           /weixin/** = anon           /**= authc</value></property></bean>

2.web.xml

<filter>    <filter-name>shiroFilter</filter-name>    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>    <init-param>      <param-name>targetFilterLifecycle</param-name>      <param-value>true</param-value>    </init-param>  </filter>  <filter-mapping>    <filter-name>shiroFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping>

3.java代码

import java.io.Serializable;  import java.util.Collection;  import java.util.Collections;  import java.util.concurrent.TimeUnit;    import javax.annotation.PostConstruct;    import org.apache.shiro.session.Session;  import org.apache.shiro.session.UnknownSessionException;  import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.beans.factory.annotation.Value;  import org.springframework.context.annotation.Lazy;  import org.springframework.data.redis.core.RedisTemplate;  import org.springframework.stereotype.Component;  @SuppressWarnings({"rawtypes","unchecked"})  @Component("collectionRedisSessionDao")  @Lazy(false)  public class CollectionRedisSessionDao extends AbstractSessionDAO {      private static Logger logger = LoggerFactory.getLogger(CollectionRedisSessionDao.class);      @Autowired      private RedisTemplate redisTemplate;     // @Value("${redis.key.prefix}")      private String redisPrefixKey="redisPrefixKey";      /**      * The Redis key prefix for the sessions      */      private String keyPrefix = "shiro_redis_session:";      private String getKey(String originalKey) {          return redisPrefixKey + keyPrefix+originalKey;      }      @PostConstruct      public void init(){          logger.info("注入催收的序列/反序列类");          CollectionSerializer<Serializable> collectionSerializer=CollectionSerializer.getInstance();          redisTemplate.setDefaultSerializer(collectionSerializer);          //redisTemplate默认采用的其实是valueSerializer,就算是采用其他ops也一样,这是一个坑。          redisTemplate.setValueSerializer(collectionSerializer);      }            @Override      public void update(Session session) throws UnknownSessionException {          logger.debug("更新seesion,id=[{}]", session.getId().toString());          try {              redisTemplate.opsForValue().set(getKey(session.getId().toString()), session,30,TimeUnit.MINUTES);          } catch (Exception e) {              logger.error(e.getMessage(),e);          }      }        @Override      public void delete(Session session) {          logger.debug("删除seesion,id=[{}]", session.getId().toString());          try {              String key=getKey(session.getId().toString());              redisTemplate.delete(key);          } catch (Exception e) {              logger.error(e.getMessage(),e);          }        }        @Override      public Collection<Session> getActiveSessions() {          logger.info("获取存活的session");          return Collections.emptySet();      }        @Override      protected Serializable doCreate(Session session) {          Serializable sessionId = generateSessionId(session);          assignSessionId(session, sessionId);          logger.debug("创建seesion,id=[{}]", session.getId().toString());          try {              redisTemplate.opsForValue().set(getKey(session.getId().toString()), session,30,TimeUnit.MINUTES);          } catch (Exception e) {              logger.error(e.getMessage(),e);          }          return sessionId;      }        @Override      protected Session doReadSession(Serializable sessionId) {            logger.debug("获取seesion,id=[{}]", sessionId.toString());          Session readSession = null;          try {              readSession=(Session) redisTemplate.opsForValue().get(getKey(sessionId.toString()));          } catch (Exception e) {              logger.error(e.getMessage());          }          return readSession;      }              } 

import org.apache.commons.lang3.SerializationUtils;  import java.io.Serializable;  import org.springframework.data.redis.serializer.RedisSerializer;  import org.springframework.data.redis.serializer.SerializationException;  public class CollectionSerializer<T extends Serializable> implements RedisSerializer<T>{      private CollectionSerializer(){}      public static volatile CollectionSerializer<Serializable> collectionSerializer=null;      public static CollectionSerializer<Serializable> getInstance(){          if(collectionSerializer==null){              synchronized (CollectionSerializer.class) {                  if(collectionSerializer==null){                      collectionSerializer=new CollectionSerializer<>();                  }              }          }          return collectionSerializer;      }      @Override      public byte[] serialize(T t) throws SerializationException {          return SerializationUtils.serialize(t);      }        @Override      public T deserialize(byte[] bytes) throws SerializationException {          return SerializationUtils.deserialize(bytes);      }      }  






原创粉丝点击