springboot使用ssh公钥连接mysql(含账号密码连接)

引言

在项目开发过程中,遇到了连接数据库时需要使用ssh公钥的情况。在本地使用navicat可以直接通过可视化界面去进行ssh的连接,但是在java中无法直接去进行连接。

后来经过查询资料,发现必须要在java中编写相关配置文件后才可以正常连接。

问题解决

原理:程序在本机创建ssh连接,连接到ssh server,然后再发送数据库操作指令,指令会被转发到目标数据库服务器上,返回操作结果

**前提:**项目已经配置好mysql连接所需要参数

**注意:**我演示的是使用ssh的公钥模式进行连接,如果需要使用密码模式进行连接,需要打开和关闭某些注释

  1. 引入依赖

    <dependency>
        <groupId>com.jcraft</groupId>
        <artifactId>jsch</artifactId>
        <version>0.1.55</version>
    </dependency>
    
  2. 编写ssh连接配置类

    package com.lzj.config;
    
    import com.jcraft.jsch.JSch;
    import com.jcraft.jsch.JSchException;
    import com.jcraft.jsch.Session;
    
    import java.util.Properties;
    
    /**
     * <p>
     *  SSH连接配置类
     * </p>
     *
     * @author:雷子杰
     * @date:2023/3/4
     */
    public class SSHConnectionConfig {
    
        //本地的ssh中的knownhost文件路径
        private String SSH_PATH_FILE_KNOWN_HOSTS = "C:\\Users\\86158\\.ssh\\known_hosts";
        //本地的ssh密钥路径
        private String SSH_PATH_FILE_PRIVATE_KEY = "**********************************";
        //ssh连接的用户名
        private String SSH_USER = "******";
        //ssh远程连接的ip地址
        private String SSH_REMOTE_SERVER = "65.115.26.30";
        //ssh连接的端口号,一般默认为22
        private Integer SSH_REMOTE_PORT = 22;
        //SSH使用密码
        //private String sshPassword;
    
        //本地mysql发起连接的IP地址
        private String MYSQL_REMOTE_SERVER = "127.0.0.1";
        //本地数据库连接时用的端口号(不能填3306)
        private Integer LOCAl_PORT = 3307;
        //远程数据库端口用的端口号
        private Integer REMOTE_PORT = 3309;
    
        //com.jcraft.jsch.Session;
        private Session session;
    
        /**
         * 关闭ssh连接
         */
        public void closeSSH() {
            session.disconnect();
        }
    
        /**
         * 创建ssh连接
         */
        public void createSSH() throws JSchException {
            JSch jSch = new JSch();
    
            //下面这两个设置是在公钥模式需要设置的,非公钥模式不需要进行设置
            //设置known_hosts文件路径,如:~/.ssh/known_hosts(known_hosts中存储是已认证的远程主机host key)
            jSch.setKnownHosts(SSH_PATH_FILE_KNOWN_HOSTS);
            //设置私钥
            jSch.addIdentity(SSH_PATH_FILE_PRIVATE_KEY);
    
            session = jSch.getSession(SSH_USER, SSH_REMOTE_SERVER, SSH_REMOTE_PORT);
    
            //如果是密码模式需要设置密码
            //session.setPassword(sshPassword);
    
            //设置连接过程不校验known_hosts文件中的信息
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
    
            //ssh 建立连接!
            session.connect();
    
            //根据安全策略,您必须通过转发端口进行连接
            session.setPortForwardingL(LOCAl_PORT, MYSQL_REMOTE_SERVER, REMOTE_PORT);
        }
    }
    
  3. 编写监听器

    注意:

    1. Listener类使用@WebListener注解;
    2. SpringBoot的启动类需要增加@ServletComponentScan用于扫描加载Listener类;

    经过我的尝试,发现如果使用了@Component注解,就算不使用@WebListener也同样可以完成监听功能

    package com.lzj.config;
    
    import org.springframework.stereotype.Component;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.annotation.WebListener;
    
    /**
     * <p>
     *
     * </p>
     *
     * @author:雷子杰
     * @date:2023/3/4
     */
    @Component//尽量加上这个
    @WebListener//声明为监听器
    public class MyContextListener implements ServletContextListener {
    
        private SSHConnectionConfig sshConnectionConfig;
    
        public MyContextListener() {
            super();
        }
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("Context initialized ... !");
            try {
                sshConnectionConfig = new SSHConnectionConfig();
                sshConnectionConfig.createSSH();
            } catch (Throwable e) {
                e.printStackTrace(); // 连接失败
            }
    
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("Context destroyed ... !");
            sshConnectionConfig.closeSSH();//断开ssh连接
        }
    }
    
  4. 注意可能需要修改你的mysql连接配置

    可以看见我的的url中的localhost:3307,这个ip和端口号是根据你编写的ssh配置类MYSQL_REMOTE_SERVERLOCAl_PORT来的,你可能需要进行修改

    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        username: root
        password: ******
        url: jdbc:mysql://localhost:3307/leopard-vendor_cloud?autoReconnect=true&useUnicode=true&useSSL=false
    
  5. 测试

    编写一个测试类测试数据库的连接

    package com.lzj;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import javax.sql.DataSource;
    import java.sql.SQLException;
    
    /**
     * <p>
     *
     * </p>
     *
     * @author:雷子杰
     * @date:2023/3/3
     */
    @SpringBootTest(classes = SpringbootDetabaseApplication.class)
    @RunWith(SpringRunner.class)
    public class InitTest {
    
        @Autowired
        private DataSource dataSource;
    
        @Test
        public void testDataSource() throws SQLException {
    
            System.out.println(dataSource.getConnection());
        }
    }
    

    测试结果如下:

    image-20230304155236024

    可以发现控制台正常输出了连接相关信息

总结

image-20230304160003390

**注意:**数据库连接地址由原来的123.mysql.com:3306改为127.0.0.1:3307,这样子,ssh连接会为每一个127.0.0.1:3307上的操作转发到123.mysql.com:3306上去,便可以正常操作数据库了。ssh连接的创建,可以采用私钥的方式,亦可以采用用户名密码的方式。

参考文章

Spring Boot应用中连接到MinIO服务器,并使用公钥进行身份验证,你需要做以下几步: 1. **安装依赖**:首先确保你在pom.xml或build.gradle(对于Gradle项目)中添加了支持MinIO客户端的Spring Cloud Storage依赖。例如,如果你使用的是Maven,添加: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>com.github[minio]</groupId> <artifactId>spring-cloud-starter-minio</artifactId> </dependency> ``` 2. **配置MinIO**:创建一个配置类,如ApplicationConfig或application.properties(YAML格式),配置MinIO的基本信息,包括endpoint、accessKey和secretKey(注意这里不应公开,最好使用环境变量): ```properties minio.server-url=http://your-minio-server.com minio.access-key=your-access-key minio.secret-key=your-secret-key ``` 为了使用公钥,还需要配置SSH相关的信息,如: ```properties minio.ssh.private-key-file=path/to/your/private-key.pem minio.ssh.public-key-file=path/to/your/public-key.pub ``` 3. **应用安全配置**:在Spring Security配置中,如果你已经启用,需要配置公钥认证: ```java @Bean public JschClientAuth sshClientAuth() { return new JschClientAuth("publickey", "path/to/your/public-key.pem"); } ``` 4. **启动应用**:最后,启动Spring Boot应用并尝试连接MinIO,你应该能通过公钥方式进行无密码的身份验证。 **重要提示:**记得管理好你的私钥,不应该直接暴露在配置文件中,而应该从环境变量或安全存储中读取。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱学习的大雄

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

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

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

打赏作者

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

抵扣说明:

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

余额充值