Implement desensitization of interface return data through custom Jackson annotations in SpringBoot

Scenes

Integrate Sharding Sphere in SpringBoot to realize data encryption and decryption/data desensitization/database ciphertext, query plaintext:

Integrate Sharding Sphere in SpringBoot to realize data encryption and decryption/data desensitization/database ciphertext, and query plaintext - Programmer Sought

The above is about storing ciphertext in the database, and using the plaintext desensitization method when querying. If it is necessary to store in the database

plaintext, and the processed data returned during query, such as ID number, mobile phone number and other sensitive data, can be used in the following ways.

Note:

Blog:
Overbearing rogue temperament blog_CSDN Blog-C#, Architecture Road, Blogger in SpringBoot

accomplish

1. Custom Jackson annotations

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive {
    //脱敏策略
    SensitiveStrategy strategy();
}

2. Specify the desensitization strategy. This rule is formulated according to the specific needs of the business. The following is only a demonstration

import java.util.function.Function;

/**
 * 脱敏策略,枚举类,针对不同的数据定制特定的策略
 */
public enum SensitiveStrategy {
    /**
     * 用户名
     */
    USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
    /**
     * 身份证
     */
    ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
    /**
     * 手机号
     */
    PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
    /**
     * 地址
     */
    ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****"));

    private final Function<String, String> desensitizer;
    SensitiveStrategy(Function<String, String> desensitizer) {
        this.desensitizer = desensitizer;
    }
    public Function<String, String> desensitizer() {
        return desensitizer;
    }
}

3. Custom JSON serialization implementation

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import java.io.IOException;
import java.util.Objects;

/**
 * 序列化注解自定义实现
 * JsonSerializer<String>:指定String 类型,serialize()方法用于将修改后的数据载入
 */
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
    private SensitiveStrategy strategy;
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws
            IOException {
        gen.writeString(strategy.desensitizer().apply(value));
    }
    /**
     * 获取属性上的注解属性
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws
            JsonMappingException {
        Sensitive annotation = property.getAnnotation(Sensitive.class);
        if (Objects.nonNull(annotation)&&Objects.equals(String.class,
                property.getType().getRawClass())) {
            this.strategy = annotation.strategy();
            return this;
        }
        return prov.findValueSerializer(property.getType(), property);
    }
}

4. Add the User class, add annotations to the fields that need to be desensitized, and specify the desensitization strategy

import com.badao.demo.sensitive.Sensitive;
import com.badao.demo.sensitive.SensitiveStrategy;
import lombok.Data;
import java.io.Serializable;

@Data
public class User implements Serializable {

    private static final long serialVersionUID = -5514139686858156155L;

    private Integer id;

    private Integer userId;

    @Sensitive(strategy = SensitiveStrategy.USERNAME)
    private String name;

    private Integer age;

}

5. Write a controller for testing

@RequestMapping("user")
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("save")
    public String save() {
        User user = new User();
        user.setUserId(new Random().nextInt( 1000 ) + 1);
        user.setName("badao"+user.getUserId());
        user.setAge(new Random().nextInt( 80 ) + 1);
        userService.insert(user);
        return "save success";
    }

    @RequestMapping("select")
    public User select() {
        List<User> all = userService.findAll();
        return all.size()>0?all.get(0):new User();
    }
}

Test effect

 

Guess you like

Origin blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131749770