集团官网
  • 国家级全民数字素养与技能培训基地
  • 河南省第一批产教融合型企业建设培育单位
  • 郑州市数字技能人才(码农)培养评价联盟

Java培训:什么是sMybatisPlus数据安全?

编辑:云和数据 日期:2022-12-01 15:52

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

应用场景

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

API介绍

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

 

1669012039360_1.jpg

1669011956303_2.jpg

代码实现

1.创建mp工程

创建maven工程,结构如下:

1669012124855_3.jpg

2.代码编写

pom.xml

                        org.springframework.boot            spring-boot-starter-web                            com.baomidou            mybatis-plus-boot-starter            3.4.1                            mysql            mysql-connector-java                            org.projectlombok            lombok            provided            

application.yml

spring:  datasource:    url: jdbc:mysql://localhost:3306/springboot?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai    driver-class-name: com.mysql.cj.jdbc.Driver    username: root    password: rootmybatis-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 */@Datapublic 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 */@Repositorypublic 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 */@Servicepublic 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 {    @Autowired    private UserService userService;    @GetMapping    public 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);    }}

1669012363492_4.jpg

替换配置文件

spring:  datasource:    url: mpw:wT9PqZ9Hf4VWgXDuZ/Z1JKfdDyS0sSu3+O2qDkJ/Ulnabpq3z1lZbiThWseQ4DQSx3+SWpufsTysjdYhn6Scsa77AzIIaUgv8DZ17gPxAq88AISmxd9OjxidmY50uBVMkGhP9qAted45zuHBzVrw6Q==    driver-class-name: com.mysql.cj.jdbc.Driver    username: mpw:Pnh++mI45YrC4s6JveJYaA==    password: mpw:Pnh++mI45YrC4s6JveJYaA==mybatis-plus:  type-aliases-package: com.itheima.pojo

添加启动参数

1669012409610_5.jpg

运行效果

1669012455176_6.jpg

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 {    @Override    public 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,如果没有配置,则给它配置上,这样就不用在启动时添加参数来运行了。

1669012544198_7.jpg

实现

创建配置工程mysafe

1669012588892_8.jpg

代码清单

pom.xml

    spring-boot-starter-parent    org.springframework.boot    2.3.8.RELEASE            org.springframework.boot        spring-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 {    @Override    public 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")));        }    }    @Override    public int getOrder() {        return 0;    }}

spring.factories

“`.properties

ert.version=b440fe7fd55dbe26

org.springframework.boot.env.EnvironmentPostProcessor=\

com.itheima.SafetyEncryptProcessor

“`

ert.properties

“`properties

ert.version=2ac6625cb3188f52

“`

安装到本地仓库

1669012678475_9.jpg

修改mp工程添加依赖

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

    com.itheima    mysafe    1.0-SNAPSHOT

4.测试结果

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

1669012734787_10.jpg

总结

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

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

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

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

相关内容

抢先一步 鸿蒙(HarmonyOS)应用开发者高级认证 免费考! 适合人群计算机相关专业在校生(技师、中职、高职、本科、研究生)对鸿蒙(HarmonyOS)有兴趣的非计算机相关专业在校生目前正在从事移动应用的开发者目前正在从事计算机行业相关的人计算机专业高校老师所有对鸿蒙(HarmonyOS)有兴趣的人 培训方案掌握鸿蒙的核心概念和端云一体化开发、... 什么是Java的多态性(polymorphism)?它有哪些不同的形式? 多态性是Java面向对象编程的一个重要概念,它允许不同的对象以一致的方式响应同一个方法调用,具体表现为对象在运行时可以表现出多个不同的形态。多态性主要有两种不同的形式:编译时多态性(静态多态性)和运行时多态性(动态多态性)。1. 编译时多态性(静态多态性):   ... 如何学习和搭建Hadoop开发环境? Hadoop是大数据处理领域的重要平台,能够处理和分析大量数据。为了有效地利用Hadoop,我们需要学习其基础知识,并正确搭建开发环境。下面是详细的学习和搭建指南。一、学习Hadoop基础掌握基础概念和原理Hadoop主要由HDFS和MapReduce两部分组成。HDFS是分布式文件系统,Ma... UI 设计学习如何进阶成为高手 我总结了六种方法,帮助你走出舒适区,提高技能,成长为自信且经验丰富的UI设计高手一位经验丰富的 UI 设计师,往往十分看中应用程序界面的吸引力和视觉刺激,确保满足用户期望和需求。但是,如果你已经在 UI 设计圈摸爬滚打多年,仍然没有出色的作品,那你极有可能是因为陷入了一个舒适圈,UI技能一直原... 在Java中Executor和Executors的区别? 在Java中,Executor和Executors都与线程池和并发执行有关,但它们是不同的概念和类。1.ExecutorExecutor是一个接口,位于java.util.concurrent包中,用于表示一个执行任务的执行器。它只定义了一个方法:void execute(Runnable c... String类型的常见命令有哪些? String类型,也就是字符串类型,是Redis中最简单的存储类型。其value是字符串,不过根据字符串的格式不同,又可以分为3类:string是普通字符串,int整数类型,可以做自增、自减操作,float浮点类型,可以做自增、自减操作。String的常见命令有:SET:添加或者修改已经存在的...