• 解决使用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 }
  • 相关阅读:
    派生
    什么是类的继承
    python中一切皆对象
    类之属性查找
    类之 __init__方法

    MySql cmd下的学习笔记 —— 有关分组的操作(group by)
    MySql cmd下的学习笔记 —— 有关select的操作(max, min等常见函数)
    MySql cmd下的学习笔记 —— 有关select的操作(in, and, where, like等等)
    MySql cmd下的学习笔记 —— 有关表的操作(对表的增删改查)
  • 原文地址:https://www.cnblogs.com/xhq1024/p/11869068.html
Copyright © 2020-2023  润新知