| package doumeemes.config.shiro; | 
|   | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.apache.commons.lang.SerializationUtils; | 
| import org.apache.shiro.session.Session; | 
| import org.apache.shiro.session.UnknownSessionException; | 
| import org.apache.shiro.session.mgt.SimpleSession; | 
| import org.apache.shiro.session.mgt.eis.SessionDAO; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.data.redis.core.RedisTemplate; | 
| import org.springframework.data.redis.core.StringRedisTemplate; | 
|   | 
| import java.io.Serializable; | 
| import java.util.Collection; | 
| import java.util.concurrent.TimeUnit; | 
|   | 
| //@Component | 
| @Slf4j | 
| @SuppressWarnings({ "rawtypes", "unchecked" }) | 
| public class ShiroRedisSessionDAO  implements SessionDAO { | 
| // Session超时时间,单位为毫秒 | 
| private static final String KEY_PREFIX = "shiro:session:"; | 
|     private long expireTime = 120000; | 
|     @Autowired | 
|     private ShiroTokenManager shiroTokenManager; | 
|     @Autowired | 
|     private RedisTemplate redisTemplate;// Redis操作类,对这个使用不熟悉的,可以参考前面的博客 | 
|   | 
|     public ShiroRedisSessionDAO() { | 
|   | 
|         super(); | 
|   | 
|     } | 
|   | 
|     public ShiroRedisSessionDAO(long expireTime, StringRedisTemplate redisTemplate) { | 
|   | 
|         super(); | 
|   | 
|         this.expireTime = expireTime; | 
|   | 
|         this.redisTemplate = redisTemplate; | 
|   | 
|     } | 
|   | 
|     @Override // 更新session | 
|   | 
|     public void update(Session session) throws UnknownSessionException { | 
|   | 
|         System.out.println("===============update================"); | 
|   | 
|         if (session == null || session.getId() == null) { | 
|             return; | 
|         } | 
|         session.setTimeout(expireTime); | 
|         byte[] bytes = SerializationUtils.serialize((Serializable) session); | 
|         redisTemplate.opsForValue().set(KEY_PREFIX+session.getId(), bytes, expireTime, TimeUnit.MILLISECONDS); | 
|     } | 
|   | 
|     @Override // 删除session | 
|   | 
|     public void delete(Session session) { | 
|   | 
|         System.out.println("===============delete================"); | 
|   | 
|         if (null == session) { | 
|   | 
|             return; | 
|   | 
|         } | 
|   | 
|         redisTemplate.opsForValue().getOperations().delete(KEY_PREFIX+session.getId()); | 
|   | 
|     } | 
|   | 
|     @Override// 获取活跃的session,可以用来统计在线人数,如果要实现这个功能,可以在将session加入redis时指定一个session前缀,统计的时候则使用keys("session-prefix*")的方式来模糊查找redis中所有的session集合 | 
|     public Collection getActiveSessions() { | 
|   | 
|         System.out.println("==============getActiveSessions================="); | 
|   | 
|         return redisTemplate.keys("*"); | 
|   | 
|     } | 
|   | 
|     @Override | 
|     public Serializable create(Session session) { | 
|   | 
|         System.out.println("===============doCreate================"); | 
|   | 
|         if (session == null) { | 
|             log.error("session is null"); | 
|             throw new UnknownSessionException("session is null"); | 
|         } | 
|         Serializable sessionId = shiroTokenManager.build(); | 
|         ((SimpleSession)session).setId(sessionId); | 
|         byte[] bytes = SerializationUtils.serialize((Serializable) session); | 
|         redisTemplate.opsForValue().set(session.getId(), bytes, expireTime, TimeUnit.MILLISECONDS); | 
|         return sessionId; | 
|   | 
|     } | 
|     public Session readSession(Serializable sessionId) throws UnknownSessionException{ | 
|         if (sessionId == null) { | 
|             log.warn("session id is null"); | 
|             return null; | 
|         } | 
|         if (sessionId instanceof String) { | 
|             // 对SessionId进行验证(可用于防止Session捕获、暴力捕捉等一系列安全问题,最终安全性取决于check如何实现) | 
|             shiroTokenManager.check((String) sessionId); | 
|         } | 
|         log.debug("read session from cache"); | 
|   | 
|         SimpleSession simpleSession = (SimpleSession) SerializationUtils.deserialize((byte[])redisTemplate.opsForValue().get(KEY_PREFIX+sessionId)); | 
|        return simpleSession; | 
|   | 
|     } | 
|   | 
|     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; | 
|   | 
|     } | 
| } |