详解MybatisPlus数据安全
创始人
2024-01-30 01:34:18

MybatisPlus数据安全

概述

​ 存在数据库中的数据对于普通用户而言是不可见的,好像是藏起来了一样,但对于开发者,只要知道数据库的连接地址、用户名、密码,则数据不再安全;这也意味着,一旦连接数据库的配置文件暴露出去,则数据不再安全。

应用场景

开发中的数据库配置文件或配置中心中的配置信息

API介绍

MybatisPlus中有个针对配置项加密处理的

在这里插入图片描述

在这里插入图片描述

代码实现

1 创建mp工程

创建maven工程,结构如下:

在这里插入图片描述

2 代码编写

pom.xml

    org.springframework.bootspring-boot-starter-webcom.baomidoumybatis-plus-boot-starter3.4.1mysqlmysql-connector-javaorg.projectlomboklombokprovided

application.yml

spring:datasource:url: jdbc:mysql://localhost:3306/springboot?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: root
mybatis-plus:type-aliases-package: com.itheima.pojo

启动类

package com.itheima;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @version 1.0* @description 说明* @package com.itheima*/
@SpringBootApplication
@MapperScan(basePackages = "com.itheima.mapper")
public class App {public static void main(String[] args) {SpringApplication.run(App.class,args);}
}

pojo

package com.itheima.pojo;import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;/*** @version 1.0* @description 说明* @package com.itheima.pojo*/
@Data
public class User {private Integer id;private String username;@TableField(select = false)private String password;private String salt;}

mapper

package com.itheima.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.pojo.User;
import org.springframework.stereotype.Repository;/*** @version 1.0* @description 说明* @package com.itheima.mapper*/
@Repository
public interface UserMapper extends BaseMapper {
}

service接口与实现类

package com.itheima.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.pojo.User;/*** @version 1.0* @description 说明* @package com.itheima.service*/
public interface UserService extends IService {
}
package com.itheima.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.springframework.stereotype.Service;/*** @version 1.0* @description 说明* @package com.itheima.service.impl*/
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {
}

controller

package com.itheima.controller;import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** @version 1.0* @description 说明* @package com.itheima.controller*/
@RestController
@RequestMapping("user")
public class UserController {@Autowiredprivate UserService userService;@GetMappingpublic List listAll(){return userService.list();}}

启动测试

生成加密后的内容
package com.itheima;import com.baomidou.mybatisplus.core.toolkit.AES;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @version 1.0* @description 说明* @package com.itheima*/
@SpringBootApplication
@MapperScan(basePackages = "com.itheima.mapper")
public class App {public static void main(String[] args) {String secretKey = AES.generateRandomKey();System.out.println("secretKey:" + secretKey);String url = AES.encrypt("jdbc:mysql://localhost:3306/springboot?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai", secretKey);String username = AES.encrypt("username", secretKey);String password = AES.encrypt("password", secretKey);System.out.println("url=" +url );System.out.println("username=" +username );System.out.println("password=" +password );SpringApplication.run(App.class,args);}
}

在这里插入图片描述

替换配置文件
spring:datasource:url: mpw:wT9PqZ9Hf4VWgXDuZ/Z1JKfdDyS0sSu3+O2qDkJ/Ulnabpq3z1lZbiThWseQ4DQSx3+SWpufsTysjdYhn6Scsa77AzIIaUgv8DZ17gPxAq88AISmxd9OjxidmY50uBVMkGhP9qAted45zuHBzVrw6Q==driver-class-name: com.mysql.cj.jdbc.Driverusername: mpw:Pnh++mI45YrC4s6JveJYaA==password: mpw:Pnh++mI45YrC4s6JveJYaA==
mybatis-plus:type-aliases-package: com.itheima.pojo
添加启动参数

在这里插入图片描述

运行效果

在这里插入图片描述

3 优化

目的

启动时,需要指定密钥 才能使用,如果我们把它封装到一个jar里,让它启动时自动去加载密钥,且密钥可配置,那这样就更灵活了。

分析

通过查看MybatisPlus加载的源码,其做解密处理的类如下:

/** Copyright (c) 2011-2020, baomidou (jobob@qq.com).* 

* Licensed under the Apache License, Version 2.0 (the "License"); you may not* use this file except in compliance with the License. You may obtain a copy of* the License at*

* https://www.apache.org/licenses/LICENSE-2.0*

* Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the* License for the specific language governing permissions and limitations under* the License.*/ package com.baomidou.mybatisplus.autoconfigure;import com.baomidou.mybatisplus.core.toolkit.AES; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.boot.env.OriginTrackedMapPropertySource; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.core.env.SimpleCommandLinePropertySource;import java.util.HashMap;/*** 安全加密处理器** @author hubin* @since 2020-05-23*/ public class SafetyEncryptProcessor implements EnvironmentPostProcessor {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {/*** 命令行中获取密钥*/String mpwKey = null;for (PropertySource ps : environment.getPropertySources()) {if (ps instanceof SimpleCommandLinePropertySource) {SimpleCommandLinePropertySource source = (SimpleCommandLinePropertySource) ps;mpwKey = source.getProperty("mpw.key");break;}}/*** 处理加密内容*/if (StringUtils.isNotBlank(mpwKey)) {HashMap map = new HashMap<>();for (PropertySource ps : environment.getPropertySources()) {if (ps instanceof OriginTrackedMapPropertySource) {OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource) ps;for (String name : source.getPropertyNames()) {Object value = source.getProperty(name);if (value instanceof String) {String str = (String) value;if (str.startsWith("mpw:")) {map.put(name, AES.decrypt(str.substring(4), mpwKey));}}}}}// 将解密的数据放入环境变量,并处于第一优先级上if (CollectionUtils.isNotEmpty(map)) {environment.getPropertySources().addFirst(new MapPropertySource("custom-encrypt", map));}}} }

其使用了SPI原理,在类所在的jar下的META-INF/spring.factories中配置了这个SafetyEncryptProcessor。那我们能否也来定义一个这样的配置处理器,判断环境配置中是否配置了–mpw.key,如果没有配置,则给它配置上,这样就不用在启动时添加参数来运行了。

实现

创建配置工程mysafe

在这里插入图片描述

代码清单

pom.xml

spring-boot-starter-parentorg.springframework.boot2.3.8.RELEASE

org.springframework.bootspring-boot-starter

SafetyEncryptProcessor

package com.itheima;import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StringUtils;import java.io.IOException;
import java.util.Properties;/*** @version 1.0* @description 说明* @package com.itheima*/
public class SafetyEncryptProcessor implements EnvironmentPostProcessor, Ordered {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {Properties pro = new Properties();try {pro.load(new ClassPathResource("ert.properties").getInputStream());} catch (IOException e) {e.printStackTrace();}/*** 命令行中获取密钥*/String mpwKey = null;for (PropertySource ps : environment.getPropertySources()) {if (ps instanceof SimpleCommandLinePropertySource) {SimpleCommandLinePropertySource source = (SimpleCommandLinePropertySource) ps;mpwKey = source.getProperty("mpw.key");break;}}if(StringUtils.isEmpty(mpwKey)){environment.getPropertySources().addFirst(new SimpleCommandLinePropertySource("mySpringApplicationCommandLineArgs", "--mpw.key=" + pro.getProperty("ert.version")));}}@Overridepublic int getOrder() {return 0;}
}

spring.factories

ert.version=b440fe7fd55dbe26
org.springframework.boot.env.EnvironmentPostProcessor=\
com.itheima.SafetyEncryptProcessor

ert.properties

ert.version=2ac6625cb3188f52
安装到本地仓库

在这里插入图片描述

修改mp工程添加依赖

修改pom.xml,添加mysafe的依赖

com.itheimamysafe1.0-SNAPSHOT

4 测试结果

去除启动时的参数设置。再启动后访问页面、效果如下:

在这里插入图片描述

总结

  1. MybatisPlus利用了springboot的配置信息增强器与SPI机制来实现对配置文件中敏感数据的解密处理。

  2. mysafe工程打成的jar包,将来就上传到企业的内部服务器上,当密钥变更时,重新打包即可。

  3. 而我们将来布署项目到服务器上时,也肯定存在配置文件,一旦配置信息暴露,则数据库就危险了。通过加密手段能够让破解者增加破解阻碍。

  4. 此次练习仅做抛砖引玉作用,关于加密与解密是没有做到那么严谨的,需要结合自己公司实际情况去调整。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
函授本科是什么 自考本科还是函... 很多小伙伴在选择学历提升方式的时候,可能会感到很迷茫,不知道报考自考本科还是函授本科,两者有什么区别...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
安徒生童话有哪些 安徒生童话的... 从德国汉堡港乘轮船渡波罗的海抵丹麦王国,就到了安徒生的祖邦。安徒生(1805-1875)以童话作品闻...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...