spring.config.import를 사용하여 외부 설정 파일을 가져올 때 Jasypt의 자동 복호화가 제대로 동작하지 않는 문제는 프로퍼티 소스(Property Source)의 로딩 순서 때문에 발생합니다.
문제의 원인: 로딩 순서의 충돌
- Spring Boot 2.4 이상부터
spring.config.import도입: 이 기능은application.properties보다 더 높은 우선순위로 외부 설정 파일을 가져오기 위해 설계되었습니다. (예:config/app.yml,optional:classpath:/default.properties등) - Jasypt의 동작 시점: Jasypt는 스프링의
Environment가 준비되는 과정에서 프로퍼티 소스들을 래핑(wrapping)하여ENC(...)값을 복호화합니다. - 충돌 지점:
spring.config.import는 Jasypt가 프로퍼티 소스를 처리할 준비를 마치기 전에 먼저 동작하여 외부 파일을 로드하려고 시도할 수 있습니다. 이 과정에서 아직 복호화되지 않은ENC(...)형태의 값을 그대로 읽어오려고 하면서 문제가 발생하거나, Jasypt의 복호화 프로세스가import된 프로퍼티에 적용되지 않는 현상이 발생합니다.
결론적으로, Jasypt의 복호화 로직이 적용되어야 할 시점과 spring.config.import가 동작하는 시점이 꼬이면서 발생하는 문제입니다.
해결 방법: jasypt.encryptor.bootstrap=true 설정
Jasypt 라이브러리는 이 문제를 해결하기 위한 공식적인 옵션을 제공합니다. 바로 jasypt.encryptor.bootstrap 프로퍼티입니다.
- 핵심 기능: 이 값을
true로 설정하면, Jasypt는 스프링 부트의 가장 이른 초기화 단계(bootstrap phase)에서 자신을 등록합니다. - 동작 방식:
- Jasypt가 “나 먼저 복호화 준비할게!”라고 가장 먼저 손을 듭니다.
- 스프링 부트가
spring.config.import를 포함한 모든 설정 파일을 읽어오기 시작합니다. - 이때 Jasypt는 이미 대기하고 있다가, 로드되는 모든 프로퍼티 소스에 대해
ENC(...)값을 즉시 복호화하여 메모리에 적재합니다. - 따라서
spring.config.import로 가져오는 파일 안에 있는ENC(...)값도 문제없이 복호화됩니다.
적용 방법
application.properties (또는 .yml) 파일에 아래 두 줄을 추가하는 것이 가장 간단하고 확실한 해결책입니다.
application.properties
properties
|
1 2 3 4 5 6 7 8 |
<span class="line"><span># Jasypt가 스프링 부트의 bootstrap 과정에서 동작하도록 설정</span></span> <span class="line"><span>jasypt.encryptor.bootstrap=true</span></span> <span class="line"><span></span></span> <span class="line"><span># Jasypt 비밀 키 설정 (환경 변수 또는 JVM 옵션으로 관리하는 것이 가장 좋음)</span></span> <span class="line"><span>jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD}</span></span> <span class="line"><span></span></span> <span class="line"><span># 기존에 사용하던 spring.config.import 설정은 그대로 둡니다.</span></span> <span class="line"><span>spring.config.import=optional:classpath:/config/real-db.properties, optional:file:./config/api-keys.properties</span></span> |
application.yml
YAML
|
1 2 3 4 5 6 7 8 9 10 |
<span class="line"><span>jasypt</span><span>:</span></span> <span class="line"><span> encryptor</span><span>:</span></span> <span class="line"><span> bootstrap</span><span>: </span><span>true</span></span> <span class="line"><span> password</span><span>: </span><span>${JASYPT_ENCRYPTOR_PASSWORD}</span></span> <span class="line"></span> <span class="line"><span>spring</span><span>:</span></span> <span class="line"><span> config</span><span>:</span></span> <span class="line"><span> import</span><span>:</span></span> <span class="line"><span> - </span><span>"optional:classpath:/config/real-db.properties"</span></span> <span class="line"><span> - </span><span>"optional:file:./config/api-keys.properties"</span></span> |
real-db.properties (예시)
properties
|
1 2 3 4 |
<span class="line"><span># spring.config.import로 가져오는 외부 파일</span></span> <span class="line"><span>spring.datasource.url=jdbc:mysql://real-db-server:3306/prod_db</span></span> <span class="line"><span>spring.datasource.username=prod_user</span></span> <span class="line"><span>spring.datasource.password=ENC(aBcDeFgHiJkLmNoPqRsTuVwXyZ12345==)</span></span> |
이 방법을 사용했을 때의 흐름
- 애플리케이션 시작.
- Jasypt가
jasypt.encryptor.bootstrap=true설정을 발견. - Jasypt가 스프링의 프로퍼티 처리 시스템에 최우선 순위로 등록됨.
- 스프링이
spring.config.import를 처리하여real-db.properties파일을 읽음. - 파일을 읽는 즉시, Jasypt가
ENC(...)로 된 비밀번호를 가로채서 복호화함. - 복호화된 평문 비밀번호가 스프링의
Environment에 최종적으로 등록됨. - 이후
DataSourceBean이 생성될 때, 정상적으로 복호화된 비밀번호를 사용하여 DB 커넥션을 맺음.
요약
spring.config.import와 Jasypt의 자동 복호화 기능을 함께 사용할 때 EncryptionOperationNotPossibleException이 발생하거나 복호화가 안 되는 문제는 프로퍼티 로딩 순서의 충돌 때문입니다.
이 문제의 가장 확실하고 공식적인 해결책은 application.properties에 jasypt.encryptor.bootstrap=true를 추가하여, Jasypt가 다른 모든 프로퍼티 처리보다 먼저 동작하도록 우선순위를 높여주는 것입니다.