JAVA实现数据脱敏(结合Spring)

前言

这个数据脱敏是最近做的一个权限系统的功能,我们这个权限系统包含菜单权限,操作权限,数据权限,字段权限,其中字段权限就是控制字段根据不同的角色隐藏或者显示,这个和数据脱敏也是差不多的,正儿八经的数据脱敏如用户的身份证后几位为**** ,或则如用户电话号码不全部展示,如187 **** 9101,我们做的这种字段权限并不是用****替代,而是这个字段直接不给前端展示!

设计方案

每个接口根据不同的业务模块来控制字段的显示,那么我们可以设计一个注解,这个注解是用来标注当前接口使用哪个业务模块,然后通过业务模块code得到当前接口需要隐藏的字段。然后做一个controller的后置处理即可。这里只是涉及到字段权限控制,后续完整的权限系统涉及会通过其他文章分享出来!

核心代码

权限注解

/**
 * @description: 权限二期权限鉴定注解
 * @author TAO
 * @date 2021/7/13 3:53 下午
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PreAuthorize {
    /**
     * 角色(多个用英文逗号隔开)
     * @return
     */
  

    /**
     * 权限
     * 注意:格式:moduleName+"_"+permissionName 例如:项目_查看
     * @return
     */
    


    /**
     * 数据权限模块code设置
     * @return
     */
    String moduleCode() default "";

    /**
     * 忽略平台
     * @return
     */
    



}

这里只提供字段权限相关的

Controller使用

@ApiOperation(value = "根据id获取信息", authorizations = @Authorization(value = "token"))
    @GetMapping("/{id}")
    @PreAuthorize(moduleCode = "project_module")
    public ResponseEntity<Project> info(@PathVariable Long id) {

Controller后置处理


@ControllerAdvice
public class DesensitizeResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body == null) {
            return null;
        }
        //得到需要屏蔽的字段
        Set<String> fieldAuthority =  RequestContext.getCurrentHideFieldS();
        if (CollectionUtils.isEmpty(fieldAuthority)) {
            return body;
        }

        if (body instanceof Page) {
            return pageDesensitize(body,fieldAuthority);
        }else{
            return objectDesensitize(body,fieldAuthority);
        }

    }


    //返回值为Page时,数据字段脱敏处理
    public Object pageDesensitize(Object page,Set<String> fieldAuthority) {
        Page newPage = (Page) page;
        List<?> records = newPage.getRecords();
        if (CollectionUtils.isEmpty(records)){
            return page;
        }

        SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
        fieldAuthority.forEach(field ->{
            filter.getExcludes().add(field);
        });

        Class<?> c = records.get(0).getClass();
        newPage.setRecords(JSONObject.parseArray(JSONObject.toJSONString(records, filter),c));
        return newPage;
    }

    //返回值普通对象,数据字段脱敏处理
    public Object objectDesensitize(Object object,Set<String> fieldAuthority) {
        SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
        fieldAuthority.forEach(field ->{
            filter.getExcludes().add(field);
        });

        return JSONObject.parseObject(JSON.toJSONString(object, filter), object.getClass());
    }

}

RequestContext.getCurrentHideFieldS();这个数据在请求认证的时候获取用户权限信息的时候就统一查出来存储在ThreadLocal中,关于ThreadLocal这里不过多讲,需要了解的可以看看往期文章ThreadLocal-同一个线程共享数据,这里只需要知道通过RequestContext.getCurrentHideFieldS();能得到需要隐藏的字段!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员劝退师-TAO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值