配置不能进JAR包,必须外部注入:通过--spring.config.additional-location挂载敏感配置文件,配合非root容器用户与严格文件权限,杜绝明文泄露;禁用DEBUG日志防止密码打印。

application.yml 里的数据库密码、密钥、证书路径一旦打进 JAR,就等于把钥匙塞进快递盒一起寄出去——收件人拆开就能看到。这不是“要不要加密”的问题,而是“配置根本不能进构建产物”。
spring.profiles.active 必须外部指定,不能写死在 application.yml
Spring Boot 启动时会按 profile 加载配置,但如果你在 application.yml 里写:
spring:
profiles:
active: prod那无论你用什么环境启动,它都会先加载 application-prod.yml ——而这个文件如果也打包进 JAR,敏感字段就暴露了。
- 启动时必须用参数控制:
java -jar app.jar --spring.profiles.active=prod - 或通过环境变量:
SPRING_PROFILES_ACTIVE=prod java -jar app.jar - 构建时禁止把
application-prod.yml放进src/main/resources;它应该放在部署机的独立目录(如/opt/app/config/),再用--spring.config.location=file:/opt/app/config/指定
spring.config.location 和 spring.config.additional-location 的行为差异
这两个参数都用来加载外部配置,但语义不同:
-
spring.config.location是完全替换默认加载路径(包括 classpath:/application.yml),慎用,容易漏掉通用配置 -
spring.config.additional-location是追加加载,更安全,推荐用于覆盖敏感项
例如:
java -jar app.jar \ --spring.config.additional-location=file:/etc/app/application-secret.yml
只要 application-secret.yml 里只写 spring.datasource.password=xxx 这类覆盖项,其他配置仍走 classpath,逻辑清晰、不易出错。
- 文件路径必须带
file:前缀,否则 Spring Boot 会当成 classpath 路径去查 - 多个 location 用英文逗号分隔,顺序靠后优先级越高
- 如果文件不存在,Spring Boot 默认静默忽略(除非配置了
spring.config.import并显式声明optional:false)
Docker 容器里怎么安全挂载配置而不暴露权限
OpenJDK 镜像(如 openjdk:17-jre-slim)默认以 root 运行,但生产容器不该用 root 启动 Java 进程。常见错误是:
- 把
application-secret.yml直接 COPY 进镜像 → 配置固化在镜像层,不可变、难审计 - 用
docker run -v /host/secret:/app/config挂载,但宿主机文件权限为644→ 容器内 root 可读,普通用户也可读(如果容器降权运行,反而可能读不到)
正确做法:
- 宿主机上设好权限:
chown 1001:1001 /host/secret.yml && chmod 600 /host/secret.yml(假设容器内非 root 用户 UID=1001) - Dockerfile 里创建非 root 用户并切换:
USER 1001 - 启动命令里用
--spring.config.additional-location=file:/app/config/application-secret.yml,路径与挂载目标一致
这样即使有人拿到容器镜像,也拿不到配置文件;即使拿到宿主机备份,没权限也打不开。
加密配置不是银弹,jasypt-spring-boot-starter 有硬伤
有人想用 jasypt 对 application.yml 里字段加密,比如:
spring:
datasource:
password: ENC(abc123...)这看似安全,实则引入新风险:
- 加密密钥必须传给应用,通常靠环境变量
JASYPT_ENCRYPTOR_PASSWORD→ 密钥本身又成了新敏感项 - JVM 参数、进程列表、/proc/
/environ 都可能泄露该环境变量 - 若密钥硬编码在代码或配置里,等于把锁和钥匙焊在一起
真正可控的做法只有两个:
一是配置彻底不进 JAR,全靠外部注入;
二是用 Vault、Nacos Config、Apollo 这类配置中心,在启动时动态拉取,密钥由平台统一托管。
最常被忽略的一点:日志。哪怕配置没进 JAR,如果启动时打印了 DataSource 初始化详情,密码可能出现在 logs/spring.log 里。务必检查日志级别,禁用 org.springframework.boot.autoconfigure.jdbc 的 DEBUG 日志。


















