飞歌笔记--springBoot2.0以redis的方式实现session共享

在查看相关redis方法实现session共享时,其实只需要替换sessionDao就可以实现。不用实现redisManage。

具体代码如下:RedisSessionDao.class

package com.fg.car.backweb.shiro;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

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.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import com.fg.car.framework.config.RedisObjectSerializer;
/**
 * ********************************************* 
 * @ClassName: RedisSessionDao  
 * @Description:TODO(这里用一句话描述这个类的作用) 
 * @Author ganjing  
 * @Date 2018年11月14日
 * @Copyright: 2018 天誉飞歌(重庆)研究院版权所有 
 **********************************************
 */
@Configuration
@Service
public class RedisSessionDao extends AbstractSessionDAO {  
    private static Logger logger = LoggerFactory.getLogger(RedisSessionDao.class);
   
    @Autowired
    private RedisTemplate<String, Object> template;
    
    private String keyPrefix = "shiro-session:";  
    private String getKey(String key) {  
        return keyPrefix+key;  
    }   
    /**
     *   ************************************************** 
     * @Title: update  
     * @Description: 修改session  
     * @Param:@param session
     * @Param:@throws UnknownSessionException   
     * @see org.apache.shiro.session.mgt.eis.SessionDAO#update(org.apache.shiro.session.Session) 
     ****************************************************
     */
    @Override  
    public void update(Session session) throws UnknownSessionException {  
        logger.debug("更新seesion,id=[{}]", session.getId().toString());  
        try {  
            getRedisTemplate().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 {  
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
            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");  
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        Set<Session> sessions = new HashSet<>();
        Set<String> keys = redisTemplate.keys(getKey("*"));
        if (keys != null && keys.size() > 0) {
            for (String key : keys) {
                Session s = (Session) redisTemplate.opsForValue().get(key);
                sessions.add(s);
            }
        }
        return sessions;
    }  
  
    @SuppressWarnings("rawtypes")
    @Override  
    protected Serializable doCreate(Session session) {  
        Serializable sessionId = generateSessionId(session);  
        assignSessionId(session, sessionId);  
        logger.debug("创建seesion,id=[{}]", session.getId().toString());  
        try {  
            getRedisTemplate().opsForValue().set(sessionId.toString(),session); 
        } catch (Exception e) {  
            e.printStackTrace();
            logger.error(e.getMessage(),e);  
        }  
        return sessionId;  
    }  
  
    @SuppressWarnings("rawtypes")
    @Override  
    protected Session doReadSession(Serializable sessionId) {  
        logger.debug("获取seesion,id=[{}]", sessionId.toString());  
        Session readSession = null;  
        try { 
            Object obj   = getRedisTemplate().opsForValue().get(sessionId.toString());
            readSession = (Session)obj;
        } catch (Exception e) { 
            e.printStackTrace();
            logger.error(e.getMessage());  
        }  
        return readSession;  
    }  
    public RedisTemplate<String, Object> getRedisTemplate(){
        RedisTemplate<String, Object> template1 = new RedisTemplate<String, Object>();
        template1.setConnectionFactory(template.getConnectionFactory());
        template1.setKeySerializer(new StringRedisSerializer());
        template1.setValueSerializer(new RedisObjectSerializer());
        template1.afterPropertiesSet();
        return template1;
    }

}

注意:session序列化时只能自己实现RedisObjectSerializer的,不能使用Jackson2JsonRedisSerializer。会保存。

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;

import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;

import com.fg.car.backweb.shiro.OAuth2Filter;
import com.fg.car.backweb.shiro.OAuth2Realm;
import com.fg.car.backweb.shiro.RedisSessionDao;
import com.fg.car.backweb.shiro.ShiroLifecycleBeanPostProcessorConfig;

ShiroConfig.class

/**
 * ********************************************* 
 * @ClassName: ShiroConfig  
 * @Description:shiro配置
 * @Author ganjing  
 * @Date 2018年11月5日
 * @Copyright: 2018 天誉飞歌(重庆)研究院版权所有 
 **********************************************
 */
@Configuration
@AutoConfigureAfter(ShiroLifecycleBeanPostProcessorConfig.class)
@Service
public class ShiroConfig {
    @Autowired
    private RedisSessionDao redisSessionDao;
    private static final String NAME = "custom.name";
    private static final String VALUE = "/";
    

     @Bean
        public DefaultWebSessionManager sessionManager(RedisSessionDao sessionDAO, SimpleCookie simpleCookie) {
            DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
            sessionManager.setSessionDAO(redisSessionDao);
            sessionManager.setSessionIdCookieEnabled(true);
            sessionManager.setSessionIdCookie(simpleCookie);
            return sessionManager;
        }
     
        @Bean
        public SimpleCookie simpleCookie() {
            SimpleCookie simpleCookie = new SimpleCookie();
            simpleCookie.setName(NAME);
            simpleCookie.setValue(VALUE);
            return simpleCookie;
        }


    @Bean("securityManager")
    public SecurityManager securityManager(OAuth2Realm oAuth2Realm, SessionManager sessionManager) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setSessionManager(sessionManager);
        //manager.setCacheManager(redisCacheManager);
        manager.setRealm(oAuth2Realm);
        return manager;
    }

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        //oauth过滤
        Map<String, Filter> filters = new HashMap<>();
        filters.put("oauth2", new OAuth2Filter());
        shiroFilter.setFilters(filters);

        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/webjars/**", "anon");
        filterMap.put("/druid/**", "anon");
        filterMap.put("/app/**", "anon");
        filterMap.put("/login", "anon");
        filterMap.put("/swagger/**", "anon");
        filterMap.put("/v2/api-docs", "anon");
        filterMap.put("/swagger-ui.html", "anon");
        filterMap.put("/swagger-resources/**", "anon");
        filterMap.put("/captcha.jpg", "anon");
        filterMap.put("/**", "oauth2");
        shiroFilter.setFilterChainDefinitionMap(filterMap);

        return shiroFilter;
    }
  
   
   
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
        proxyCreator.setProxyTargetClass(true);
        return proxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

}

ShiroLifecycleBeanPostProcessorConfig类

@Configuration
public class ShiroLifecycleBeanPostProcessorConfig {
 
    /**
     * Shiro生命周期处理器
     *
     * @return
     */
    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
 
}

注意上面标注为红色的地方只能单独写一个类。不能放到shiroConfig里面,不然@Bean无法注入。

package com.fg.car.framework.config;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

RedisObjectSerializer类

/**
 * ********************************************* 
 * @ClassName: RedisObjectSerializer  
 * @Description:redis序列化对象
 * @Author ganjing  
 * @Date 2018年11月14日
 * @Copyright: 2018 天誉飞歌(重庆)研究院版权所有 
 **********************************************
 */
public class RedisObjectSerializer implements RedisSerializer<Object> {
    private Converter<Object, byte[]> serializer = new SerializingConverter();
    private Converter<byte[], Object> deserializer = new DeserializingConverter();
    static final byte[] EMPTY_ARRAY = new byte[0];

    public Object deserialize(byte[] bytes) {
        if (isEmpty(bytes)) {
            return null;
        }
        try {
            return deserializer.convert(bytes);
        } catch (Exception ex) {
            throw new SerializationException("Cannot deserialize", ex);
        }
    }

    public byte[] serialize(Object object) {
        if (object == null) {
            return EMPTY_ARRAY;
        }
        try {
            return serializer.convert(object);
        } catch (Exception ex) {
            return EMPTY_ARRAY;
        }
    }

    private boolean isEmpty(byte[] data) {
        return (data == null || data.length == 0);
    }
}

猜你喜欢

转载自blog.csdn.net/ganjing222/article/details/84192464
今日推荐