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; 
 | 
  
 | 
    } 
 | 
} 
 |