【问题标题】:What's the best way to store a Database Password (required in a JDBC connection string) in Java?在 Java 中存储数据库密码(JDBC 连接字符串中需要)的最佳方法是什么?
【发布时间】:2021-06-18 13:53:08
【问题描述】:

我目前正在开发一个使用 JDBC 连接到 Azure DB 的 Java 应用程序。这就是我当前的代码的样子 -

File file = new File("filename.txt");
      Scanner scanner = new Scanner(file);
String pwd = scanner.nextLine();

String connectionUrl =
    "jdbc:sqlserver:{A link here};" +
    "database={DBName}; +
    "user={UserName};" +
    "password=" + pwd + ";"
    "encrypt=true;" +
    "trustServerCertificate=false;" +
    "hostNameInCertificate=*.database.windows.net;" +
    "loginTimeout=30;";

我打算在完成后在 Github 上公开上传这个项目,显然在那里有一个纯文本密码似乎是一个糟糕的主意。

但是,我不确定最好的方法是什么。我不认为存储散列密码会起作用,因为数据库字符串需要纯文本。我能想到的最好的办法是将密码存储在一个文本文档中(连同其他几个单词/文本),并使用 IO reader/substrings/BufferedReader 将其作为变量读取。对于普通读者来说,这至少在某种程度上掩盖了它,但任何了解基本 Java 的人仍然能够识别它(或者只需输入一个简单的 System.out.print(pwd))

似乎应该有更好的方法,但我还没有找到任何可行的解决方案来阻止用户打开文本文档/conf 文件并读取密码。我想保持连接完全自动化,所以不想提示用户输入密码。 对如何实现这一点的回应将不胜感激!

我是一名(主要是自学成才的)学生,在 Java 方面实践经验有限,如果我错过了一个相当明显的解决方案,敬请见谅。

【问题讨论】:

    标签: java jdbc passwords


    【解决方案1】:

    通常这些值存储在系统环境变量中。

    例如,设置以下系统变量:

    1. DATABASE_URL=<your url>
    2. DATABASE_NAME=<your database name>
    3. DATABASE_USER_NAME=<your database user name>
    4. DATABASE_USER_PASSOWRD=<your database user password>

    然后在代码中使用System.getProperty("DATABASE_URL") 等检索它们。 或者更好的办法是将所有连接 URL 存储在系统环境变量中:

    1. DATABASE_CONNECTION_URL=jdbc:sqlserver:someUrl...

    您可以在official documentationhere on StackOverflow 中看到一些示例,如何在 Azure 中设置系统环境变量。

    【讨论】:

      【解决方案2】:

      外部化配置信息

      最好的方法是外部化部署时配置信息。

      通过外部化配置信息,您不再负责维护该信息。部署您的 Java 应用程序的 sysadmin 承担着这一责任。当发生更改时,例如将数据库移动到不同的服务器,或作为安全预防措施轮换密码,无需更改您的代码库,也无需您作为程序员参与。

      目录命名服务

      为此目的设计了一些服务器,通常称为directory service or a name service。您可以选择此类服务器,包括开源/免费和商业服务器。此类服务器通常遵守LDAP 协议。

      JNDI

      Java 为您的应用程序提供了一个与目录/命名服务器交互的接口,而无需在编译时知道特定的服务器。该接口称为Java Naming and Directory Interface (JNDI)

      Oracle 提供了一个tutorial on JNDI,尽管它现在可能已经过时了。可能仍然是一种很好的免费定向方式。

      DataSource

      对于数据库连接配置信息,您通常会使用 JNDI 向目录命名服务请求实现DataSource 接口的对象。然后你只需在该对象上调用getConnection 方法。该方法将Connection 返回到您的数据库,您可以通过它执行JDBC 工作。

      应用服务器

      如果您正在构建Jakarta EE 应用程序,您的运行时容器(例如 Tomcat、Jetty、Glassfish、Payara、Wildfly、JBoss 等)可能会捆绑目录命名服务的实现。

      在运行时,应用服务器的系统管理员配置数据库服务器网络地址、网络端口号、数据库用户名和密码等连接信息。该配置信息封装在您通过 JNDI 获得的 DataSource 对象中。

      开始

      如果您刚刚开始构建应用程序,则无需立即设置 LDAP 服务器、配置 JNDI 等。留到以后再说吧。

      刚开始时,只需使用DataSource 对象即可在整个代码库中获取数据库连接。在您的代码库中的某个位置,例如应用程序生命周期的启动,hard-code 一个 DataSource 对象。稍后,当您的应用程序接近完成时,您可以使用 JNDI 将硬编码的 DataSource 对象切换为软编码,以获取 DataSource

      您的JDBC driver 可能包含一个DataSource 实现以用于您的硬编码。例如:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-14
        • 2020-05-03
        • 2017-08-02
        • 2010-09-24
        • 2010-09-05
        • 2011-05-27
        • 2020-09-09
        • 1970-01-01
        相关资源
        最近更新 更多