1.問題描述
在使用redis時,配置自定義序列化redisTemplate為FastJsonRedisSerializer .
1 /** 2 * 自定義redis序列化器 3 */ 4 @SuppressWarnings("unchecked") 5 @Bean("redisTemplate") 6 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) { 7 8 RedisTemplate<Object, Object> template = new RedisTemplate<>(); 9 // 配置連接工廠 10 template.setConnectionFactory(factory); 11 12 // 使用fastJson序列化 13 FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class); 14 15 // key的序列化采用StringRedisSerializer 16 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 17 template.setKeySerializer(stringRedisSerializer); 18 template.setHashKeySerializer(stringRedisSerializer); 19 20 // value值的序列化采用fastJsonRedisSerializer 21 template.setValueSerializer(fastJsonRedisSerializer); 22 template.setHashValueSerializer(fastJsonRedisSerializer); 23 24 return template; 25 }
redis中數據結構為:{"@type":"com.***.UserEntity","id":"1177881490377158658","nickName":"test"}
在反序列化時報錯 com.alibaba.fastjson.JSONException: autoType is not support.
二.原因分析
2017年3月15日,fastjson官方發布安全升級公告,該公告介紹fastjson在1.2.24及之前的版本存在代碼執行漏洞,當惡意攻擊者提交一個精心構造的序列化數據到服務端時,由於fastjson在反序列化時存在漏洞,可導致遠程任意代碼執行。
自1.2.25及之后的版本,禁用了部分autotype的功能,也就是”@type”這種指定類型的功能會被限制在一定范圍內使用。
而由於反序列化對象時,需要檢查是否開啟了autotype。所以如果反序列化檢查時,autotype沒有開啟,就會報錯。
三.解決辦法
官方給出的開啟autotype的方法:enable_autotype
我采用的第一種:在代碼中配置白名單
1 import com.alibaba.fastjson.JSON; 2 import com.alibaba.fastjson.parser.ParserConfig; 3 import com.alibaba.fastjson.serializer.SerializerFeature; 4 import org.springframework.data.redis.serializer.RedisSerializer; 5 import org.springframework.data.redis.serializer.SerializationException; 6 7 import java.nio.charset.Charset; 8 9 /** 10 * 自定義redis序列化 11 * 12 * @param <T> 13 * @author xhq 14 * @version 1.0 15 * @date 2019年11月15日 16 */ 17 public class FastJsonRedisSerializer<T> implements RedisSerializer<T> { 18 19 private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); 20 private Class<T> clazz; 21 22 /** 23 * 添加autotype白名單 24 * 解決redis反序列化對象時報錯 :com.alibaba.fastjson.JSONException: autoType is not support 25 */ 26 static { 27 ParserConfig.getGlobalInstance().addAccept("com.***.UserEntity"); 28 } 29 30 public FastJsonRedisSerializer(Class<T> clazz) { 31 super(); 32 this.clazz = clazz; 33 } 34 35 @Override 36 public byte[] serialize(T t) throws SerializationException { 37 if (null == t) { 38 return new byte[0]; 39 } 40 return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); 41 } 42 43 @Override 44 public T deserialize(byte[] bytes) throws SerializationException { 45 if (null == bytes || bytes.length <= 0) { 46 return null; 47 } 48 String str = new String(bytes, DEFAULT_CHARSET); 49 return JSON.parseObject(str, clazz); 50 } 51 52 }