Mybatis加密解密查询操作(sql前),where要传入加密后的字段时遇到的问题

项目场景:

提示:这里简述项目相关背景:

例如:Mybatis加密解密查询操作(sql前),where要传入加密后的字段时遇到的问题


问题描述

提示:这里描述项目中遇到的问题:

例如:数据传输过程中数据不时出现丢失的情况,偶尔会丢失一部分数据
APP 中接收数据代码:

public Object intercept(Invocation invocation) throws Throwable {ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget();// 获取传入的参数对象Object parameterObject = parameterHandler.getParameterObject();if (parameterObject instanceof Map) {Map<?, ?> paramMap = (Map<?, ?>) parameterObject;for (Map.Entry<?, ?> entry : paramMap.entrySet()) {Object key = entry.getKey();Object value = entry.getValue();// 对于带有 @Sensitive 注解的字段,进行加密处理if (value != null && !value.toString().isEmpty()) {  // 判空和空字符串检查// 反射检查该字段是否标记了 @Sensitive 注解if (isSensitiveField(value)) {String encryptedValue = SensitiveDataUtils.encrypt(value.toString(), SM4_KEY);((Map<Object, Object>) paramMap).put(key, encryptedValue);}}}} else {// 处理非 Map 类型的参数(如单个对象查询)encryptSensitiveFields(parameterObject);}// 执行原始逻辑return invocation.proceed();}
这个方法有问题啊

原因分析:

提示:这里填写问题的分析:

是的,这个 intercept 方法存在几个潜在问题,可能导致在处理加密字段时出现错误。以下是详细的分析和改进建议:

  1. parameterObject 为 Map 类型时的处理
    在你当前的代码中,如果 parameterObject 是 Map 类型,会迭代其中的 key-value 对并检查每个 value 是否标记了 @Sensitive 注解,进而进行加密处理。这里有几个潜在问题:

value 可能是复杂对象:目前的判断条件是 if (value != null && !value.toString().isEmpty()),但是 value 可能是一个复杂对象(例如 User 对象),而不是一个简单的 String 类型。在这种情况下,直接使用 value.toString() 可能并不能反映实际字段的内容。

isSensitiveField 反射问题:你尝试通过反射检查 value 是否包含 @Sensitive 注解,但是 value 很可能是一个普通的 Java 对象(如 AdminUserDO),直接传给 isSensitiveField 可能会导致反射错误。

  1. parameterObject 不是 Map 类型时的处理
    如果 parameterObject 不是 Map 类型,你使用 encryptSensitiveFields(parameterObject) 来处理加密。该方法会检查对象中的字段并加密被 @Sensitive 注解标记的字段。问题在于,你并没有考虑 parameterObject 可能是一个嵌套对象,或者该对象的类型可能没有适当的 getter 方法,导致反射出错。

  2. 改进建议
    我们需要确保在处理 Map 类型和非 Map 类型的参数时,都能正确处理嵌套对象和字段加密。


解决方案:

提示:这里填写该问题的具体解决方案:

package cn.iocoder.yudao.framework.mybatis.core.handler;import cn.iocoder.yudao.framework.annotation.Sensitive;
import cn.iocoder.yudao.framework.mybatis.core.util.SensitiveDataUtils;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.plugin.*;import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.util.Map;import static cn.iocoder.yudao.framework.mybatis.core.util.SensitiveDataUtils.SM4_KEY;@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class})
})
public class SensitiveDataEncryptInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget();// 获取传入的参数对象Object parameterObject = parameterHandler.getParameterObject();// 如果是 Map 类型的参数if (parameterObject instanceof Map) {Map<?, ?> paramMap = (Map<?, ?>) parameterObject;for (Map.Entry<?, ?> entry : paramMap.entrySet()) {Object key = entry.getKey();Object value = entry.getValue();// 判断 value 是否为带有 @Sensitive 注解的字段,进行加密处理if (value != null) {// 对 value 进行加密String encryptedValue = encryptSensitiveValue(value);// 如果字段需要加密,替换 Map 中的值if (encryptedValue != null) {// 强制转换为 Map<Object, Object> 来避免类型问题((Map<Object, Object>) paramMap).put(key, encryptedValue);}}}} else {// 如果不是 Map 类型,处理对象的字段加密encryptSensitiveFields(parameterObject);}// 执行原始逻辑return invocation.proceed();}private String encryptSensitiveValue(Object value) throws Exception {if (value instanceof String && isSensitiveField(value)) {// 对象字段加密处理return SensitiveDataUtils.encrypt(value.toString(), SM4_KEY);}return null;}private boolean isSensitiveField(Object value) {// 判断该对象字段是否带有 @Sensitive 注解Class<?> clazz = value.getClass();for (Field field : clazz.getDeclaredFields()) {if (field.isAnnotationPresent(Sensitive.class)) {return true;  // 该字段带有 @Sensitive 注解}}return false;}private void encryptSensitiveFields(Object parameterObject) throws Exception {// 遍历对象的字段,检查是否带有 @Sensitive 注解Field[] fields = parameterObject.getClass().getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(Sensitive.class)) {field.setAccessible(true);Object value = field.get(parameterObject);if (value != null) {String encryptedValue = SensitiveDataUtils.encrypt(value.toString(), SM4_KEY);field.set(parameterObject, encryptedValue);}}}}
}

主要改进点:

encryptSensitiveValue 方法:

这个方法首先检查传入的 value 是否是需要加密的字段,如果是,则进行加密。
通过调用 isSensitiveField(value) 来判断是否需要加密,而不直接依赖 value.toString()。

isSensitiveField 方法:

通过反射检查 value 对象是否包含带有 @Sensitive 注解的字段。之前可能存在错误的反射逻辑,这里是基于对象字段的反射检查。

encryptSensitiveFields 方法:

遍历 parameterObject 的字段,并加密带有 @Sensitive 注解的字段。处理对象字段时,直接通过反射获取字段并进行加密。
其他注意事项:
确保 SensitiveDataUtils.encrypt 方法能够正确处理所有类型的 value,尤其是对于非 String 类型的对象,可能需要进一步优化加密处理。
如果 parameterObject 是一个复杂的对象,确保该对象的所有字段都可以通过反射访问(即字段为 public 或者使用了 setAccessible(true))。
这样修改后,应该能够有效避免反射错误并正确处理加密逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/493038.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

顺序表的操作

注意位序和数组下标的关系 插入&#xff1a; 插入的时间复杂度&#xff1a; 最深层语句&#xff1a; 最好情况 最坏情况 平均情况 删除&#xff1a; 查找&#xff1a;

以腾讯混元模型为例,在管理平台上集成一个智能助手

背景 前几天&#xff0c;公司的同事们一起吃了个饭&#xff0c;餐桌上大家聊到大模型的落地场景。我个人在去年已经利用百度千帆平台写过案例&#xff0c;并发过博客&#xff08;传送门&#x1f449;&#xff1a;利用文心千帆打造一个属于自己的小师爷&#xff09;&#xff0c…

计算机基础 试题

建议做的时候复制粘贴,全部颜色改为黑色,做完了可以看博客对答案。 一、单项选择题(本大题共25小题,每小题2分,共50分〉 1.计算机内部采用二进制数表示信息,为了便于书写,常用十六进制数表示。一个二进制数0010011010110用十六进制数表示为 A.9A6 B.26B C.4D6 D.…

[机器学习]XGBoost(3)——确定树的结构

XGBoost的目标函数详见[机器学习]XGBoost&#xff08;2&#xff09;——目标函数&#xff08;公式详解&#xff09; 确定树的结构 之前在关于目标函数的计算中&#xff0c;均假设树的结构是确定的&#xff0c;但实际上&#xff0c;当划分条件不同时&#xff0c;叶子节点包含的…

【AI驱动的数据结构:包装类的艺术与科学】

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 包装类装箱和拆箱阿里巴巴面试题 包装类 在Java中基本数据类型不是继承来自Object&#xff0c;为了…

探索Moticon智能传感器鞋垫OpenGo的功能与优势

Moticon智能传感器鞋垫OpenGo是一款专为运动科学和临床研究设计的先进工具。它通过13枚压力传感器、1枚3D加速器和1枚温度传感器&#xff0c;实时监测脚部的压力分布和步态变化。用户可以通过配套的Beaker应用&#xff0c;将这些数据以图表形式呈现&#xff0c;便于分析和理解。…

hive注释comment中文乱码解决

问题描述 当使用以下命令查看表的元数据信息时出现中文乱码&#xff08;使用的是idea连接hive&#xff09; desc formatted test.t_archer; 解决 连接保存hive元数据的MySQL数据库&#xff0c;执行以下命令&#xff1a; use hive3; show tables;alter table hive3.COLUMNS_…

模型 结构化思维

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。分步拆解&#xff0c;系统思考。 1 结构化思维的应用 1.1 提升销售额的结构化思维应用案例 小李是一家电商公司的运营经理&#xff0c;面对激烈的市场竞争&#xff0c;公司希望在下个季度实现销售额…

uniApp上传文件踩坑日记

最近在做移动端app&#xff0c;开始接触uniapp。想着直接用PC端的前后端API去做文件上传&#xff0c;但是uniapp的底层把请求拆成了普通请求和文件上传请求&#xff0c;所以不能用一个axios去做所有请求的处理&#xff0c;拆成uni.request和uni.uploadFile去分别处理两种情况。…

数据压缩比 38.65%,TDengine 重塑 3H1 的存储与性能

小T导读&#xff1a;这篇文章是“2024&#xff0c;我想和 TDengine 谈谈”征文活动的三等奖作品之一。作者通过自身实践&#xff0c;详细分享了 TDengine 在高端装备运维服务平台中的应用&#xff0c;涵盖架构改造、性能测试、功能实现等多个方面。从压缩效率到查询性能&#x…

电气设计 | 低压接地系统:TN-C 、TN-S、TN-C-S、TT适用哪些场所?

电气设计 | 低压接地系统&#xff1a;TN-C 、TN-S、TN-C-S、TT适用哪些场所&#xff1f; 1、低压配电系统简介2、各种低压配电系统介绍2.1、TN-C系统2.2、TN-S系统2.3、TN-C-S 系统2.4、TT 系统2.5、IT 系统 1、低压配电系统简介 低压配电系统有TN-C、TN-S、TN-C-S、TT和IT五种…

onlyoffice连接器 二次开发 合同等制式模板化技术开发方案【三】

一、期望效果 目前曹瑞版本onlyoffice已经实现&#xff1a;书签模式 和 控件模式&#xff0c;用以支持该方案。 【图1】字段绑定 【图2】模板发起 【图3】接入表单 思路讲解&#xff1a; 业务系统开发中通常希望能够通过绑定form字段给word&#xff0c;从而达到双向同步效果&am…

word实现两栏格式公式居中,编号右对齐

1、确定分栏的宽度 选定一段文字 点击分栏&#xff1a;如本文的宽度为22.08字符 2、将公式设置为 两端对齐&#xff0c;首行无缩进。 将光标放在 公式前面 点击 格式-->段落-->制表位 在“制表位位置”输入-->11.04字符&#xff08;22.08/211.04字符&#xff09;&…

37. Three.js案例-绘制部分球体

37. Three.js案例-绘制部分球体 实现效果 知识点 WebGLRenderer WebGLRenderer 是Three.js中的一个渲染器类&#xff0c;用于将3D场景渲染到网页上。 构造器 WebGLRenderer( parameters : Object ) 参数类型描述parametersObject渲染器的配置参数&#xff0c;可选。 常用…

笔记本电脑需要一直插着电源吗?电脑一直充电的利弊介绍

笔记本电脑属于常用电子设备&#xff0c;它的便携性和功能性给我们带来了很多便利。但是&#xff0c;我们在使用笔记本电脑的时候&#xff0c;是否应该一直插着电源呢&#xff1f;这个问题可能困扰了很多人&#xff0c;因为不同的使用方式可能会对笔记本电脑的性能和寿命产生不…

深入理解延迟队列:原理、实现与应用

深入理解延迟队列&#xff1a;原理、实现与应用 1. 什么是延迟队列 延迟队列&#xff08;Delayed Queue&#xff09;是一种特殊的队列&#xff0c;它的特点是队列中的元素需要在指定的时间后才能被消费者获取和处理。与普通的先进先出&#xff08;FIFO&#xff09;队列不同&a…

内容与资讯API优质清单

作为开发者&#xff0c;拥有一套API合集是必不可少的。这个开发者必备的API合集汇集了各种实用的API资源&#xff0c;为你的开发工作提供了强大的支持&#xff01;无论你是在构建网站、开发应用还是进行数据分析&#xff0c;这个合集都能满足你的需求。你可以通过这些免费API获…

jQuery总结(思维导图+二维表+问题)

关于什么是jQuery&#xff1a;&#xff08;下面是菜鸟里的介绍&#xff09; jQuery 是一个 JavaScript 库。 jQuery 极大地简化了 JavaScript 编程。 jQuery 很容易学习。 而jQuery对我的感受就是&#xff0c;链式运用的很形象&#xff0c;隐式迭代还有一些兼容性强的优点&…

python数据分析:介绍pandas库的数据类型Series和DataFrame

安装pandas pip install pandas -i https://mirrors.aliyun.com/pypi/simple/ 使用pandas 直接导入即可 import pandas as pd pandas的数据结构 pandas提供了两种主要的数据结构&#xff1a;Series 和 DataFrame,类似于python提供list列表&#xff0c;dict字典&#xff0c;…

安装opnet14.5遇到的问题

安装opnet遇到的问题 我是按照这个教程来安装的。 然后遇到了两个问题&#xff1a; 1、“mod_dirs”目录问题 Can’t enable ETS scripting support due to missing files。 This is likely because:<opnet_release_dir>\sys\lib is notinclude in the “mod_dirs” pre…