반응형
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;
}
}
반응형
'개발 이야기 > Springboot' 카테고리의 다른 글
Testcontainers로 테스트 코드 만들기 2(with Kotlin) (0) | 2024.01.18 |
---|---|
Testcontainers로 테스트 코드 만들기 (0) | 2024.01.07 |
Springboot에서 ResourceTransformer 적용하여 뷰 페이지 렌더링 (0) | 2024.01.07 |
[Kotlin] Spring Batch를 사용한 배치 애플리케이션 작성 (0) | 2021.04.05 |
[Kotlin] Springboot, Mock을 활용한 유닛 테스트(feat. Method Stub) (0) | 2021.02.27 |