专业的编程技术博客社区

网站首页 > 博客文章 正文

SpringBoot敏感词如何实现列表脱敏,详情不脱敏的操作?

baijin 2025-01-16 17:48:39 博客文章 14 ℃ 0 评论

在之前的分享中,我们介绍了通过@JsonSerialize(using = SensitiveInfoSerializer.class) 对敏感数据进行脱敏的操作,但是这种方式实现的效果就是对全局的数据都会被脱敏,但是实际上我们想要的结果是在列表中进行脱敏处理,但是在查看详情的时候不需要进行脱敏处理。这种应该如何实现呢?下面我们就来看看如何实现。

使用自定义注解和条件序列化

首先需要我们创建一个自定义的注解,用来标识那些字段需要进行脱敏,那些字段不需要进行脱敏,标识在什么情况下需要脱敏,什么情况下不需要脱敏。

其次,我们需要在序列化操作的过程中添加上下文判断,判断是否要对操作添加脱敏处理。可以通过ThreadLocal来保存上下文信息的信息,用来区分那些是列表的查询操作,那些是详情的查看操作。如下所示,是具体的操作步骤。

创建自定义注解

创建一个自定义的注解,用来标识进行条件脱敏的操作字段。如下所示。

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Sensitive {
}

创建上下文持有类

接下来需要创建一个ThreadLocal用来保存当前操作的上下文的信息,如下所示,并且在操作中判断是否是需要被序列化的操作。

public class SerializationContext {
    private static final ThreadLocal<Boolean> isSensitive = ThreadLocal.withInitial(() -> false);

    public static boolean isSensitive() {
        return isSensitive.get();
    }

    public static void setSensitive(boolean sensitive) {
        isSensitive.set(sensitive);
    }

    public static void clear() {
        isSensitive.remove();
    }
}

修改序列化器

在序列化处理器中,根据上下文的信息来决定是否对相关的字段进行序列化脱敏操作。如下所示,如果上下文中包含了需要脱敏的操作,那么就进行脱敏,如果是不包括脱敏那么就不需要进行处理。

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

public class SensitiveInfoSerializer extends JsonSerializer<String> {

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (SerializationContext.isSensitive()) {
            gen.writeString(maskSensitiveInfo(value));
        } else {
            gen.writeString(value);
        }
    }

    private String maskSensitiveInfo(String value) {
        // 脱敏逻辑,例如用星号替换部分字符
        return "****";
    }
}

应用自定义注解和序列化器

接下来就是按照之前介绍的方案,在需要进行脱敏的字段上通过自定义的序列化器进行脱敏,并且添加自定义的注解来标识是否需要进行脱敏。如下所示。

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

public class User {
    private String username;

    @Sensitive
    @JsonSerialize(using = SensitiveInfoSerializer.class)
    private String password;

    // getters and setters
}

在控制器中设置上下文

接下来就是在Controller中设置上下文信息,可以根据不同的操作来设置不同的上下文信息。如下所示。这样就可以实现不同的操作不同的脱敏。

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping
    public List<User> getUsers() {
        SerializationContext.setSensitive(true);
        List<User> users = userService.findAll();
        SerializationContext.clear();
        return users;
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        SerializationContext.setSensitive(false);
        User user = userService.findById(id);
        SerializationContext.clear();
        return user;
    }
}

总结

通过上面的这种方式就可以实现在列表中的敏感信息是脱敏的,而在详情中的敏感信息是不脱敏的,从而快速实现不同场景的不同需求而且还不需要对业务代码进行大的修改。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表