개발 이야기/Springboot
Springboot Application 로드 시 외부 파일 읽기 & 환경 설정
농개
2024. 1. 7. 17:07
반응형
Springboot는 application.yml을 통해 환경 설정을 관리합니다.
아래와 같은 코드는 흔히 접할 수 있습니다.
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/testdb
username: <USERNAME>
password: <PASSWORD>
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
database: mysql
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
- src/resources/application.yml
만약 데이터베이스의 Username / Password를
소스코드 상에 입력하여 관리한다면 심각한 보안 문제를 야기합니다.
이 외에도 보안상 유의해야할 설정 값들이 존재합니다.
- DB 연결을 위한 계정정보
- 내/외부 IP
- 서비스 연동에 필요한 Private key
- 기타
위 문제를 해결하기 위해 아래와 같이 접근 해볼 수 있습니다.
- 중요 정보를 외부화
- Application 최초 구동 시 읽기
- 의존성 주입
중요 정보를 외부화 하는 솔루션은 다양합니다.
AWS Secretmanager, Vault, Spring Cloud Config 등...
위 내용까지 다루지는 않습니다.
여기서는 Secret Provider를 통해 서버 내 json 파일이 있다고 가정합니다.
1. 중요 정보를 외부화
아래와 같이 서버내 특정 Path에 json 파일이 존재합니다.
{
"dbUsername": "root",
"dbPassword": "root"
}
- /var/config/config.json
위 파일은 절대 원격 저장소(ex. github)에 저장하지 않습니다.
2. Application 최초 구동 시 읽기
public class JsonPropertiesParseFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class);
return new MapPropertySource("secret-config", readValue);
}
}
위와 같이 PropertiesSourceFactory를 구현합니다.
그리고 아래처럼 프로퍼티를 읽어 Bean 객체화 합니다.
@Configuration
@PropertySource(value = "file:/var/config/config.json", factory = JsonPropertiesParseFactory.class, ignoreResourceNotFound = true)
public class AppConfig {
private String userName;
private String userPassword;
@Autowired
Environment environment;
@PostConstruct
public void init() {
this.userName = environment.getProperty("dbUsername");
this.userPassword = environment.getProperty("dbUserPassword");
}
public String getUserName() {
return userName;
}
public String getUserPassword() {
return userPassword;
}
}
Springboot 구동 시, 위 Bean은 일종의 ConfigMap으로 활용할 수 있습니다.
3. 의존성 주입
이제 필요한 곳에서 주입받아 사용만 하면 됩니다.
위 예시와 같이 Mysql 연결을 위한 DB 연결 계정 정보라면
아래와 같이 Datasource를 구성해 볼 수 있습니다.
@Configuration
public class DataSourceConfig {
@Value("${spring.datasource.url}")
private String jdbcUrl;
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Autowired
private AppConfig appConfig;
@Bean
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setUsername(appConfig.getUserName());
dataSource.setPassword(appConfig.getUserPassword());
dataSource.setDriverClassName(driverClassName);
return dataSource;
}
}
반응형