解決使用Redis時配置 fastjson反序列化報錯 com.alibaba.fastjson.JSONException: autoType is not support


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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM