`
coocaobo
  • 浏览: 9086 次
社区版块
存档分类
最新评论

spring MVC 对 ResponseBody返回json数据进行脱敏处理

阅读更多

为了对springmvc框架中的json请求数据进行可控制的脱敏处理,研究了配置message-converters里面的内容,并通过重写部分方法进行脱敏修改

 

 

  • 配置message-converters 

 

  <mvc:annotation-driven>
        <!-- 处理responseBody 返回结果 -->
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <!--<bean class="com.fasterxml.jackson.databind.ObjectMapper">-->
                    <bean class="com.ez.core.servlet.SensitiveObjectMapper">
                        <property name="dateFormat">
                            <bean class="java.text.SimpleDateFormat">
                                <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
                            </bean>
                        </property>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

 

  • 需要重写的类有 “com.fasterxml.jackson.databind.ObjectMapper”, “com.fasterxml.jackson.databind.MappingJsonFactory”,“com.fasterxml.jackson.core.json.UTF8JsonGenerator”;

 

package com.ez.core.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.DefaultDeserializationContext;
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;

/**
 * Created by Administrator on 2018/2/8.
 */
public class SensitiveObjectMapper extends ObjectMapper {

    /**
     * 对弗雷的jsonfactory使用自定义工厂
     */
    public SensitiveObjectMapper() {
        super(new SensitiveJsonFactory(), (DefaultSerializerProvider) null, (DefaultDeserializationContext) null);
    }
}

 

 

 

package com.ez.core.servlet;

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.io.IOContext;
import com.fasterxml.jackson.core.json.UTF8JsonGenerator;
import com.fasterxml.jackson.databind.MappingJsonFactory;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;

/**
 * Created by Administrator on 2018/2/8.
 */
public class SensitiveJsonFactory extends MappingJsonFactory {
    public SensitiveJsonFactory() {
        super();
    }

    public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException {
        IOContext ctxt = this._createContext(out, false);
        ctxt.setEncoding(enc);
        if (enc == JsonEncoding.UTF8) {
            return this._createUTF8Generator(this._decorate(out, ctxt), ctxt);
        } else {
            Writer w = this._createWriter(out, enc, ctxt);
            return this._createGenerator(this._decorate(w, ctxt), ctxt);
        }
    }

    /**
     * 主要是重写该方法,对需要进行脱敏处理的数据,使用 SensitiveUTF8JsonGenerator 处理,
     * 不需要脱敏的数据,还是按照原来的路径进行处理
     * @param out
     * @param ctxt
     * @return
     * @throws IOException
     */
    protected JsonGenerator _createUTF8Generator(OutputStream out, IOContext ctxt) throws IOException {
        UTF8JsonGenerator gen = null;
        boolean needSensitive = !true;

        if (needSensitive) {
            gen = new SensitiveUTF8JsonGenerator(ctxt, this._generatorFeatures, this._objectCodec, out);
        } else {
            gen = new UTF8JsonGenerator(ctxt, this._generatorFeatures, this._objectCodec, out);
        }

        if (this._characterEscapes != null) {
            gen.setCharacterEscapes(this._characterEscapes);
        }

        SerializableString rootSep = this._rootValueSeparator;
//        if (rootSep != _rootValueSeparator) {
//        if(rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
        gen.setRootValueSeparator(rootSep);
//        }

        return gen;
    }


}

 

 最后需要对真正写入流的方法进行重写,通过判断是否需要进行脱敏处理,然后根据具体的脱敏规则进行处理,判断时可能需要通过当前数据的路径进行判断,所以增加了basePath存储先关路径,一般脱敏规则,是将相关数据替换为***

package com.ez.core.servlet;

import com.fasterxml.jackson.core.Base64Variant;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.io.IOContext;
import com.fasterxml.jackson.core.json.UTF8JsonGenerator;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Created by Administrator on 2018/2/8.
 */
public class SensitiveUTF8JsonGenerator extends UTF8JsonGenerator {

    private StringBuffer basePath = new StringBuffer();

    //    private String[] path = new String[];
    public SensitiveUTF8JsonGenerator(IOContext ctxt, int features, ObjectCodec codec, OutputStream out) {
        super(ctxt, features, codec, out);
    }

    public SensitiveUTF8JsonGenerator(IOContext ctxt, int features, ObjectCodec codec, OutputStream out, byte[] outputBuffer, int outputOffset, boolean bufferRecyclable) {
        super(ctxt, features, codec, out, outputBuffer, outputOffset, bufferRecyclable);
    }


    private void addPath(SerializableString name) {
        this.basePath.append(".").append(name);
    }

    private void addPath(String name) {
        this.basePath.append(".").append(name);
    }

    private void deleteOnePath() {
        int index = basePath.lastIndexOf(".");
        if (index != -1) {
            basePath.delete(index, basePath.length());
        }

    }

    private void dealRemovePath() {
        deleteOnePath();
    }

    public void writeFieldName(SerializableString name) throws IOException {
        addPath(name);
        super.writeFieldName(name);
    }

    public void writeFieldName(String name) throws IOException {
        addPath(name);
        super.writeFieldName(name);
    }

    public void writeString(String text) throws IOException {
        text = sensitiveTransfer(text);
        super.writeString(text);
    }


    public void writeString(Reader reader, int len) throws IOException {
        super.writeString(reader, len);
        dealRemovePath();
    }

    public void writeString(char[] text, int offset, int len) throws IOException {
        super.writeString(text, offset, len);
        dealRemovePath();
    }

    public void writeRawUTF8String(byte[] text, int offset, int length) throws IOException {
        super.writeRawUTF8String(text, offset, length);
        dealRemovePath();
    }

    public void writeUTF8String(byte[] text, int offset, int len) throws IOException {
        super.writeUTF8String(text, offset, len);
        dealRemovePath();
    }

    public void writeBinary(Base64Variant a, byte[] b, int c, int d) throws IOException, JsonGenerationException {
        super.writeBinary(a, b, c, d);
        dealRemovePath();
    }

    public int writeBinary(Base64Variant a, InputStream b, int c) throws IOException, JsonGenerationException {
        int ret = super.writeBinary(a, b, c);
        dealRemovePath();
        return ret;
    }


    public void writeNumber(short s) throws IOException {
        super.writeNumber(s);
        sensitiveTransfer(s);
    }

    private void sensitiveTransfer(short s) {
        sensitiveTransfer(s);
    }


    public void writeNumber(int i) throws IOException {
        super.writeNumber(i);
        sensitiveTransfer(i);
    }

    private void sensitiveTransfer(int i) {
        dealRemovePath();
    }

    public void writeNumber(long l) throws IOException {
        super.writeNumber(l);
        sensitiveTransfer(l);
    }

    private void sensitiveTransfer(long l) {
        dealRemovePath();
    }


    public void writeNumber(BigInteger value) throws IOException {
        super.writeNumber(value);
        sensitiveTransfer(value);
    }

    private void sensitiveTransfer(BigInteger value) {
        dealRemovePath();
    }

    public void writeNumber(double d) throws IOException {
        super.writeNumber(d);
        sensitiveTransfer(d);
    }

    private void sensitiveTransfer(double d) {
        dealRemovePath();
    }


    public void writeNumber(float f) throws IOException {
        super.writeNumber(f);
        sensitiveTransfer(f);
    }

    private void sensitiveTransfer(float f) {
        dealRemovePath();
    }

    public void writeNumber(BigDecimal value) throws IOException {
        super.writeNumber(value);
        sensitiveTransfer(value);
    }

    private void sensitiveTransfer(BigDecimal value) {
        dealRemovePath();
    }

    public void writeNumber(String encodedValue) throws IOException {
        encodedValue = sensitiveTransfer(encodedValue);
        super.writeNumber(encodedValue);
    }

    private String sensitiveTransfer(String encodedValue) {
        /**
         * 判断是否需要进行脱敏
         * 根据 basePath 和脱敏规则;
         */

//        String ret = encodedValue ;
        String ret = encodedValue + "脱敏";

//        System.out.println("basePath: " + basePath);
//        try {
//            System.out.println(new String(this._outputBuffer, "UTF-8"));
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
        dealRemovePath();
        return ret;
    }


    public void writeBoolean(boolean state) throws IOException {
        super.writeBoolean(state);
        sensitiveTransfer(state);
    }

    private void sensitiveTransfer(boolean state) {
        /**
         * 判断是否需要进行脱敏
         * 根据 basePath 和脱敏规则;
         */
        dealRemovePath();
    }

    public void writeNull() throws IOException {
        super.writeNull();
        dealRemovePath();
    }


}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics