[Kotlin Spring Boot] Security, JPA 환경에서 H2 In-memory DB 구축하기

정지현·2022년 7월 24일
0
post-custom-banner

현재 회사에서 스프링 부트 프로젝트를 자바로 진행하고 있는데, 이 프로젝트가 끝나면 이후 프로젝트는 코틀린으로 진행해볼까 한다.

그러기에 앞서 코틀린을 공부를 해야하는데, 코틀린을 곁들인(?) 스프링 부트로 간단히 백오피스 같은 느낌으로 개발 체크리스트 토이프로젝트를 만들어보고 싶어졌다.

초기 프로젝트를 생성하는데에 있어서 JPA 와 H2 까지는 문제가 없었는데, 시큐리티를 적용함에 있어서 발생한 문제가 몇 있어서 이를 메모차 기록해두려고 한다.


본 포스트는 스프링 부트 프로젝트 초기 생성 시 Spring JPA, Spring Security, H2 Database 를 포함하여 만들었다고 가정하고 Gradle 또는 Maven 에 의존성을 설치하는 과정은 생략한다.

.yml 설정

  h2:
    console:
      enabled: true # 콘솔을 enable 해야 H2 콘솔에 접근할 수 있다.
  datasource:
    driver-class-name: org.h2.Driver # H2 드라이버 지정
    url: jdbc:h2:mem:dchecklist;MODE=MySQL # Scheme 은 dchekclist 로, 에뮬레이트 방식은 MySQL 로 지정
    username: root # 사용할 아이디
    password: password # 사용할 패스워드

  jpa:
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
        format_sql: true
    show-sql: true
    generate-ddl: true
    database-platform: org.hibernate.dialect.MySQL8Dialect # 로그에 출력되는 쿼리 형식은 MySQL8 기준

여기서 url 키에서 jdbc:h2:mem:dchecklist;MODE=MySQL 을 지정해주었는데, 여기서 MODE 는 공식 도큐먼트에 따르면 H2 는 다른 데이터베이스의 동작 방식을 일부분 에뮬레이팅 할 수 있다고 한다.

즉, H2 를 사용하고 있긴 하지만, 데이터베이스가 동작하는 방식은 마치 MySQL 인 것 처럼 사용할 수 있다는 것이다.

For certain features, this database can emulate the behavior of specific databases. However, only a small subset of the differences between databases are implemented in this way.


난관 1

이 상태로 스프링 부트 서버를 실행시키고, /h2-console 로 접근해보자.

스프링 시큐리티에 걸려서 기본 Form Login 화면이 나온다. 그럼 시큐리티에서 Form Login 을 해제해보자.

Config 를 설정하기 위해 SecurityConfig.kt 파일을 생성하였다.

// SecurityConfig.kt
@EnableWebSecurity
class SecurityConfig {

    @Bean
    fun security(http: HttpSecurity): SecurityFilterChain {
        // formLogin 해제
        http.formLogin().disable();
        
        return http.build();
    }
   
}

사담이지만, 기존 스프링 시큐리티를 설정하기 위해서는 WebSecurityConfigurerAdapter 를 상속받고, configure 메소드를 오버라이딩했었지만, 공식 도큐먼트에 따르면 시큐리티 5.7.0 버전부터는 해당 어댑터가 Deprecated 되었다고 한다. 그 대신 SecurityFilterChain 를 Bean 으로 등록하여 사용하라고 권고한다.

In Spring Security 5.7.0-M2 we deprecated the WebSecurityConfigurerAdapter, as we encourage users to move towards a component-based security configuration.

이와 관련된 자세한 이야기는 나중에 시간이 되면 따로 포스팅해보면 좋을 것 같다.

아무튼, 본론으로 다시 돌아와서 서버를 다시 실행시켜본다.

난관 2

폼 자체는 잘 나온다. 이제 여기서 JDBC URL 의 경로를 적절히 잘 입력해주고, User NamePassword 입력 폼을 작성하고 Connect 를 눌러주자.

오.. 403 에러가 발생한다. Forbidden 이다. 즉, 접근 권한이 없어서 발생한다. 스프링 시큐리티가 아예 차단해버리는 것으로 보인다.

그렇다면 시큐리티 단에서 /h2-console 엔드포인트를 허용해주면 될 것 같다.

	// 생략
    @Bean
    fun security(http: HttpSecurity): SecurityFilterChain {
		// ...생략
        
        // h2-console 은 모두 허가
        http.authorizeRequests()
            .antMatchers("/h2-console/**").permitAll()
            
        return http.build();
    }
    // 생략

다시 실행시켜본다.

난관 3

..? 아니 동일한 오류다.. 무엇이 문제일까 싶어 CSRF 를 Disable 해주었다.

	//  생략
    @Bean
    fun security(http: HttpSecurity): SecurityFilterChain {
		// ...생략
        
        // CSRF 해제
        http.csrf().disable();

        return http.build();
    }
    // 생략

참고로, 내가 만들 프로젝트는 RestAPI 로서, 인증 방식은 JWT 를 사용할 것이기 때문에 CSRF 로부터 자유롭다고 판단되어 disable 시켜주었다.

3년 전 스택오버플로우 글이긴 하지만, 참고용으로 관련 스택오버플로우 링크를 걸어둔다.

아무튼 다시 실행시켜본다.


난관 4

오.. 이번에는 X-Frame-Option 관련한 오류가 나온다. 그래서 개발자 도구를 통해 DOM 을 살펴보았다.

frameset 태그를 사용한 것으로 보이는데, 검색해보니 각기 다른 HTML 파일을 불러와서 화면을 구성하는 방식이라고 한다. 이때 스프링 시큐리티에서는 기본적으로 X-Frame-Option 이 차단되어있다고 한다.

그렇다면 이번에 처리해야할 것은 감이 오는데, 그렇다고 모든 X-Frame-Option 에 대해서 disable() 처리를 할 것인지, 아니면 동일한 Origin 만 허용하는 sameOrigin() 정책을 적용할 것인지는 판단에 따라 다를 것 같다.

나는 sameOrigin() 을 택했다..

	// .. 생략
    @Bean
    fun security(http: HttpSecurity): SecurityFilterChain {
    	// ... 생략
        // X-Frame-Option 허용
        http.headers()
            .frameOptions()
            .sameOrigin().and();

        return http.build();
    }
    // 생략..

이제 실행시켜보자.


해결편

드디어 잘 나온다. TB_EXAMPLE 테이블에 대해서도 데이터가 잘 나온다.

끗.

profile
나를 성장시키는 좌절에 감사하고 즐기려고 노력 중
post-custom-banner

0개의 댓글