我应该在 Spring 引导项目的什么地方存储开发凭据?
Where should I store development credentials on a Spring Boot project?
我应该将开发凭据存储在 Spring 启动项目的什么位置,这样它们就不会提交到存储库?最标准的方式是什么?
在其他框架(Rails、Clojure)中,我习惯于拥有一个文件,但我不会将其提交给该信息所在的存储库。类似于辅助 application.properties 的东西被合并并且永远不会提交。有这种东西吗?
我正在部署到 Heroku,它在 Spring 可以获取的环境变量中提供凭据,因此,该部分已解决。如果我部署在其他地方,它将是一个类似的配置。
在 Spring Boot Docs, chapter 24, Externalized Configuration 中,有一个所有定义属性的地方的列表。我浏览了该列表,试图找到适当的凭据位置,但找不到:
Devtools global settings properties on your home directory
(~/.spring-boot-devtools.properties when devtools is active).
这不是 devtools 的东西,因为你可能想在本地开发禁用 devloots。
@TestPropertySource annotations on your tests.
这与测试无关
@SpringBootTest#properties annotation attribute on your tests.
再说一次,不是测试。
Command line arguments.
我不想在命令行中使用凭据,因为这些凭据往往在计算机中 public,因此,另一个程序可以获取它们。但除此之外,我在开发时不会 运行ning 命令;我正在从 IntelliJ 触发应用程序。
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
与下面的环境 variable/system 属性相同。
ServletConfig init parameters.
ServletContext init parameters.
JNDI attributes from java:comp/env.
开发本地生成 jar 时,这些似乎根本不适用,
Java System properties (System.getProperties()).
我不确定设置它们的合适方法是什么,但感觉很费力。
OS environment variables.
我要么将它们设置在我的 OS 上,这对新开发人员来说是不透明的,要么我将它们设置在 IntelliJ 运行 配置文件中,这使它们成为存储库的一部分,这就是我我正在努力避免。
A RandomValuePropertySource that only has properties in random.*.
它们不是随机的。
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
这可能是,但我不确定该文件应该存放在哪里。
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
我希望能够将配置文件特定的应用程序属性提交到存储库,因此,我无法在这些文件中存储凭据。
Application properties outside of your packaged jar (application.properties and YAML variants).
这可能是,但我不确定该文件应该存放在哪里。
Application properties packaged inside your jar (application.properties and YAML variants).
我想提交那个文件,所以我不能在那里存储凭据。
@PropertySource annotations on your @Configuration classes. Default properties
(specified using SpringApplication.setDefaultProperties).
使用类似的东西,我可以制作自己的东西,从未提交的文件中选择属性,但我有兴趣遵循 Spring Boot 的最佳和常见做法,而不是自己制作;特别是因为我才刚刚开始。
这取决于您的配置。由于 Spring 的 Environment
抽象,您可以在运行时从环境中覆盖属性,因此根据您的部署,有很多方法可以做到这一点。但是,请注意,虚假的安全感可能是真正的颈椎病。您希望将配置维护为代码 - 可以对其进行版本控制、审查和审计,而不是将其作为某人 PC 上用于注入随机运行时变量的文本文件。这是 classic "works on my machine" 问题。
你没有说任何关于你的部署的事,所以几乎不可能说;如果您使用 Tomcat,则可以使用 setenv.sh
。就目前而言,您的问题很模糊;我会在您更新 post.
时更新我的答案
编辑,根据 OP 在评论中所说:
您可以只提供键值对作为 JVM 变量。例如,如果使用 Gradle 构建,您可以执行 gradle clean bootRun -Dmy.secret.key=whatever
,并且在 build.gradle
:
bootRun {
systemProperties = System.properties
}
您还可以保留未提交给 Git 的 application-local.properties
,并使用 -Dspring.profiles.active=default,local
配置文件启动应用程序,在这种情况下 Spring 将合并 application.properties
和 application-local.properties
,后者的优先级更高。就像我之前说的,这是一个非常糟糕的想法,但你是一个自由人,所以...
Spring Boot 本身没有对加密属性的 first-class 支持,但如果你愿意自己做,你可以提交所有内容,然后启动应用程序传递密钥,或以某种方式在您的构建环境中管理它(如 Maven settings.xml
中的 属性)。
编辑 2,如何在运行时使用环境变量覆盖 application.properties
中的属性:
my.secret.key=${MY_SECRET_KEY:default}
如果环境变量 MY_SECRET_KEY
存在,my.secret.key
将等于它的值;否则它将等于 default
.
Spring-boot 允许你在不同的地方外化你的配置。对于所讨论的场景,可以在 ${PROJECT_ROOT}/config/
下放置一个 application.properties
文件。
这些属性将覆盖任何其他已定义的属性。
在这种情况下,它没有打包在可部署的工件中。
查看 Application property files 了解更多详情。
在 config/application.properties.example
下提供示例配置文件作为一个很好的起点。该文件可以进行版本控制。
为避免无意的提交,请忽略其他所有内容。
使用 git
,忽略文件可以包含以下片段(忽略除以 .example
和 README.md
结尾的文件以外的所有内容):
.gitignore:
/config/*
!/config/README.md
!/config/*.example
我应该将开发凭据存储在 Spring 启动项目的什么位置,这样它们就不会提交到存储库?最标准的方式是什么?
在其他框架(Rails、Clojure)中,我习惯于拥有一个文件,但我不会将其提交给该信息所在的存储库。类似于辅助 application.properties 的东西被合并并且永远不会提交。有这种东西吗?
我正在部署到 Heroku,它在 Spring 可以获取的环境变量中提供凭据,因此,该部分已解决。如果我部署在其他地方,它将是一个类似的配置。
在 Spring Boot Docs, chapter 24, Externalized Configuration 中,有一个所有定义属性的地方的列表。我浏览了该列表,试图找到适当的凭据位置,但找不到:
Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
这不是 devtools 的东西,因为你可能想在本地开发禁用 devloots。
@TestPropertySource annotations on your tests.
这与测试无关
@SpringBootTest#properties annotation attribute on your tests.
再说一次,不是测试。
Command line arguments.
我不想在命令行中使用凭据,因为这些凭据往往在计算机中 public,因此,另一个程序可以获取它们。但除此之外,我在开发时不会 运行ning 命令;我正在从 IntelliJ 触发应用程序。
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
与下面的环境 variable/system 属性相同。
ServletConfig init parameters. ServletContext init parameters. JNDI attributes from java:comp/env.
开发本地生成 jar 时,这些似乎根本不适用,
Java System properties (System.getProperties()).
我不确定设置它们的合适方法是什么,但感觉很费力。
OS environment variables.
我要么将它们设置在我的 OS 上,这对新开发人员来说是不透明的,要么我将它们设置在 IntelliJ 运行 配置文件中,这使它们成为存储库的一部分,这就是我我正在努力避免。
A RandomValuePropertySource that only has properties in random.*.
它们不是随机的。
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
这可能是,但我不确定该文件应该存放在哪里。
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
我希望能够将配置文件特定的应用程序属性提交到存储库,因此,我无法在这些文件中存储凭据。
Application properties outside of your packaged jar (application.properties and YAML variants).
这可能是,但我不确定该文件应该存放在哪里。
Application properties packaged inside your jar (application.properties and YAML variants).
我想提交那个文件,所以我不能在那里存储凭据。
@PropertySource annotations on your @Configuration classes. Default properties (specified using SpringApplication.setDefaultProperties).
使用类似的东西,我可以制作自己的东西,从未提交的文件中选择属性,但我有兴趣遵循 Spring Boot 的最佳和常见做法,而不是自己制作;特别是因为我才刚刚开始。
这取决于您的配置。由于 Spring 的 Environment
抽象,您可以在运行时从环境中覆盖属性,因此根据您的部署,有很多方法可以做到这一点。但是,请注意,虚假的安全感可能是真正的颈椎病。您希望将配置维护为代码 - 可以对其进行版本控制、审查和审计,而不是将其作为某人 PC 上用于注入随机运行时变量的文本文件。这是 classic "works on my machine" 问题。
你没有说任何关于你的部署的事,所以几乎不可能说;如果您使用 Tomcat,则可以使用 setenv.sh
。就目前而言,您的问题很模糊;我会在您更新 post.
编辑,根据 OP 在评论中所说:
您可以只提供键值对作为 JVM 变量。例如,如果使用 Gradle 构建,您可以执行 gradle clean bootRun -Dmy.secret.key=whatever
,并且在 build.gradle
:
bootRun {
systemProperties = System.properties
}
您还可以保留未提交给 Git 的 application-local.properties
,并使用 -Dspring.profiles.active=default,local
配置文件启动应用程序,在这种情况下 Spring 将合并 application.properties
和 application-local.properties
,后者的优先级更高。就像我之前说的,这是一个非常糟糕的想法,但你是一个自由人,所以...
Spring Boot 本身没有对加密属性的 first-class 支持,但如果你愿意自己做,你可以提交所有内容,然后启动应用程序传递密钥,或以某种方式在您的构建环境中管理它(如 Maven settings.xml
中的 属性)。
编辑 2,如何在运行时使用环境变量覆盖 application.properties
中的属性:
my.secret.key=${MY_SECRET_KEY:default}
如果环境变量 MY_SECRET_KEY
存在,my.secret.key
将等于它的值;否则它将等于 default
.
Spring-boot 允许你在不同的地方外化你的配置。对于所讨论的场景,可以在 ${PROJECT_ROOT}/config/
下放置一个 application.properties
文件。
这些属性将覆盖任何其他已定义的属性。
在这种情况下,它没有打包在可部署的工件中。
查看 Application property files 了解更多详情。
在 config/application.properties.example
下提供示例配置文件作为一个很好的起点。该文件可以进行版本控制。
为避免无意的提交,请忽略其他所有内容。
使用 git
,忽略文件可以包含以下片段(忽略除以 .example
和 README.md
结尾的文件以外的所有内容):
.gitignore:
/config/*
!/config/README.md
!/config/*.example