본문 바로가기
개발 이야기/Springboot

Springboot Application 로드 시 외부 파일 읽기 & 환경 설정

by 농개 2024. 1. 7.
반응형

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
  • 기타

 

위 문제를 해결하기 위해 아래와 같이 접근 해볼 수 있습니다.

  1. 중요 정보를 외부화
  2. Application 최초 구동 시 읽기
  3. 의존성 주입
중요 정보를 외부화 하는 솔루션은 다양합니다.
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;
	}
}

 

반응형