SpringBoot+redis 实现shiro集群,共享session。亲测可用

1.序列化工具类:

1import org.springframework.data.redis.serializer.RedisSerializer; 2import org.springframework.data.redis.serializer.SerializationException; 3 4import org.springframework.core.convert.converter.Converter; 5import org.springframework.core.serializer.support.DeserializingConverter; 6import org.springframework.core.serializer.support.SerializingConverter; 7 8/** 9 * redis序列化对象 10 */ 11public class RedisObjectSerializer implements RedisSerializer<Object> { 12 private Converter<Object, byte[]> serializer = new SerializingConverter(); 13 private Converter<byte[], Object> deserializer = new DeserializingConverter(); 14 static final byte[] EMPTY_ARRAY = new byte[0]; 15 16 public Object deserialize(byte[] bytes) { 17 if (isEmpty(bytes)) { 18 return null; 19 } 20 try { 21 return deserializer.convert(bytes); 22 } catch (Exception ex) { 23 throw new SerializationException("Cannot deserialize", ex); 24 } 25 } 26 27 public byte[] serialize(Object object) { 28 if (object == null) { 29 return EMPTY_ARRAY; 30 } 31 try { 32 return serializer.convert(object); 33 } catch (Exception ex) { 34 return EMPTY_ARRAY; 35 } 36 } 37 38 private boolean isEmpty(byte[] data) { 39 return (data == null || data.length == 0); 40 } 41}

2.从redis读写session的类:RedisSessionDAO,实现共享session

1/** 2 * redis实现共享session 3 */ 4public class RedisSessionDAO extends EnterpriseCacheSessionDAO { 5 6 private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class); 7 8 // session 在redis过期时间是30分钟30*60 9 private static int expireTime = 1800; 10 11 private static String prefix = "shiro_redis_session:"; 12 13 @Resource 14 private RedisTemplate<String, Object> redisTemplate; 15 16 17 public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { 18 this.redisTemplate = redisTemplate; 19 } 20 21 // 创建session,保存到数据库 22 @Override 23 protected Serializable doCreate(Session session) { 24 Serializable sessionId = super.doCreate(session); 25 logger.debug("创建session:{}", session.getId()); 26 redisTemplate.opsForValue().set(prefix + sessionId.toString(), session); 27 return sessionId; 28 } 29 30 // 获取session 31 @Override 32 protected Session doReadSession(Serializable sessionId) { 33 logger.debug("获取session:{}", sessionId); 34 // 先从缓存中获取session,如果没有再去数据库中获取 35 Session session = super.doReadSession(sessionId); 36 if (session == null) { 37 session = (Session) redisTemplate.opsForValue().get(prefix + sessionId.toString()); 38 } 39 return session; 40 } 41 42 // 更新session的最后一次访问时间 43 @Override 44 protected void doUpdate(Session session) { 45 super.doUpdate(session); 46 logger.debug("获取session:{}", session.getId()); 47 String key = prefix + session.getId().toString(); 48 if (!redisTemplate.hasKey(key)) { 49 redisTemplate.opsForValue().set(key, session); 50 } 51 redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); 52 } 53 54 // 删除session 55 @Override 56 protected void doDelete(Session session) { 57 logger.debug("删除session:{}", session.getId()); 58 super.doDelete(session); 59 redisTemplate.delete(prefix + session.getId().toString()); 60 } 61}

3.RedisCacheManager,实现redis进行缓存管理:

1import javax.annotation.Resource; 2 3import org.apache.shiro.cache.Cache; 4import org.apache.shiro.cache.CacheException; 5import org.apache.shiro.cache.CacheManager; 6import org.springframework.data.redis.core.RedisTemplate; 7 8public class RedisCacheManager implements CacheManager { 9 10 @Resource 11 private RedisTemplate<String, Object> redisTemplate; 12 13 @Override 14 public <K, V> Cache<K, V> getCache(String name) throws CacheException { 15 return new ShiroCache<K, V>(name, redisTemplate); 16 } 17 18 public RedisTemplate<String, Object> getRedisTemplate() { 19 return redisTemplate; 20 } 21 22 public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { 23 this.redisTemplate = redisTemplate; 24 } 25 26}

4.重写,配置缓存管理:ShiroCache<K, V>

1import java.util.ArrayList; 2import java.util.Collection; 3import java.util.List; 4import java.util.Set; 5import java.util.concurrent.TimeUnit; 6 7import org.apache.shiro.cache.Cache; 8import org.apache.shiro.cache.CacheException; 9import org.springframework.data.redis.core.RedisTemplate; 10 11@SuppressWarnings("unchecked") 12public class ShiroCache<K, V> implements Cache<K, V> { 13 14 private static final String REDIS_SHIRO_CACHE = "shiro_redis_session:"; 15 private String cacheKey; 16 private RedisTemplate<K, V> redisTemplate; 17 private long globExpire = 30; 18 19 @SuppressWarnings("rawtypes") 20 public ShiroCache(String name, RedisTemplate client) { 21// this.cacheKey = REDIS_SHIRO_CACHE + name + ":"; 22 this.cacheKey = REDIS_SHIRO_CACHE; 23 this.redisTemplate = client; 24 } 25 26 @Override 27 public V get(K key) throws CacheException { 28 redisTemplate.boundValueOps(getCacheKey(key)).expire(globExpire, TimeUnit.MINUTES); 29 return redisTemplate.boundValueOps(getCacheKey(key)).get(); 30 } 31 32 @Override 33 public V put(K key, V value) throws CacheException { 34 V old = get(key); 35 redisTemplate.boundValueOps(getCacheKey(key)).set(value); 36 return old; 37 } 38 39 @Override 40 public V remove(K key) throws CacheException { 41 V old = get(key); 42 redisTemplate.delete(getCacheKey(key)); 43 return old; 44 } 45 46 @Override 47 public void clear() throws CacheException { 48 redisTemplate.delete(keys()); 49 } 50 51 @Override 52 public int size() { 53 return keys().size(); 54 } 55 56 @Override 57 public Set<K> keys() { 58 return redisTemplate.keys(getCacheKey("*")); 59 } 60 61 @Override 62 public Collection<V> values() { 63 Set<K> set = keys(); 64 List<V> list = new ArrayList<>(); 65 for (K s : set) { 66 list.add(get(s)); 67 } 68 return list; 69 } 70 71 private K getCacheKey(Object k) { 72 return (K) (this.cacheKey + k); 73 } 74}

5.配置redisConfig:

1import org.springframework.cache.CacheManager; 2import org.springframework.context.annotation.Bean; 3import org.springframework.context.annotation.Configuration; 4import org.springframework.data.redis.cache.RedisCacheManager; 5import org.springframework.data.redis.connection.RedisConnectionFactory; 6import org.springframework.data.redis.core.RedisTemplate; 7import org.springframework.data.redis.serializer.StringRedisSerializer; 8 9import com.vcooc.experiment.utils.RedisObjectSerializer; 10/** 11 * redis配置 12 * @author Administrator 13 * 14 */ 15@Configuration 16public class RedisConfig { 17 18 @Bean 19 public CacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) { 20 RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); 21 cacheManager.setDefaultExpiration(1800); 22 return cacheManager; 23 } 24 25 //TODO 26 @Bean 27 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) { 28 RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>(); 29 template.setConnectionFactory(factory); 30 template.setKeySerializer(new StringRedisSerializer()); 31 template.setValueSerializer(new RedisObjectSerializer()); 32 return template; 33 } 34}

6.配置shiroConfig:

1import java.util.HashMap; 2import java.util.Map; 3import org.apache.shiro.session.mgt.SessionManager; 4import org.apache.shiro.spring.LifecycleBeanPostProcessor; 5import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; 6import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 7import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 8import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; 9import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; 10import org.springframework.context.annotation.Bean; 11import org.springframework.context.annotation.Configuration; 12import org.springframework.data.redis.core.RedisTemplate; 13 14import com.vcooc.experiment.shiro.RedisCacheManager; 15import com.vcooc.experiment.shiro.RedisSessionDAO; 16 17/** 18 * 19 * @author April.Chen 20 */ 21@Configuration 22public class ShiroConfig { 23 24 /* @Bean 25 public UserRealm getUserRealm() { 26 return new UserRealm(); 27 }*/ 28 29 @Bean 30 public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { 31 return new LifecycleBeanPostProcessor(); 32 } 33 34 @Bean 35 public RedisCacheManager redisCacheManager() { 36 return new RedisCacheManager(); 37 } 38 39 @Bean 40 public RedisSessionDAO redisSessionDAO() { 41 RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); 42 redisSessionDAO.setRedisTemplate(new RedisTemplate<String,Object>()); 43 return redisSessionDAO; 44 } 45 46 @Bean 47 public SessionManager sessionManager() { 48 DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); 49 sessionManager.setSessionDAO(redisSessionDAO()); 50 sessionManager.setGlobalSessionTimeout(1800); 51 sessionManager.setCacheManager(redisCacheManager()); 52 sessionManager.getSessionIdCookie().setName("vcoocUserId"); 53 return sessionManager; 54 } 55 56 @Bean 57 public DefaultWebSecurityManager securityManager() { 58 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); 59 securityManager.setSessionManager(sessionManager()); 60 securityManager.setCacheManager(redisCacheManager()); 61 return securityManager; 62 } 63 64 @Bean 65 public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() { 66 AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor(); 67 aasa.setSecurityManager(securityManager()); 68 return new AuthorizationAttributeSourceAdvisor(); 69 } 70 71 @Bean 72 public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { 73 DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator(); 74 daap.setProxyTargetClass(true); 75 return daap; 76 } 77 78 @Bean 79 public ShiroFilterFactoryBean getShiroFilterFactoryBean() { 80 Map<String, String> filterChainDefinitionMap = new HashMap<>(); 81 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 82 shiroFilterFactoryBean.setSecurityManager(securityManager()); 83 //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问--> 84 //放行静态资源 85 filterChainDefinitionMap.put("/static/**", "anon"); 86 shiroFilterFactoryBean.setLoginUrl("/toLogin"); 87 shiroFilterFactoryBean.setSuccessUrl("/index"); 88 filterChainDefinitionMap.put("/**", "anon"); 89 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); 90 return shiroFilterFactoryBean; 91 } 92}

配置redis 的property:

 redis:
    host: 127.0.0.1
    port: 6379

以上转自另外一个帖子,原帖我直接复制不可用,稍作修改,可以运行了,上面是我修改后的。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )