모각코 9주차 모임 결과 (22.09.01 / 목요일 / 15시 ~ 18시 / Google Meet)

KIMA·2022년 9월 1일
0
post-thumbnail

목표

프로그래머스 강의 듣기

결과

H2

: 별도의 설치 필요없이 로컬 개발용으로 빠르게 사용하기 좋은 경량 RDBMS 엔진

  • In-Memory 모드로 사용할 경우 어플리케이션을 재시작 할때 마다 초기화됨

설치

<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <version>1.4.2</version>
  <scope>runtime</scope>
</dependency>
  • Compile 시 의존성이 필요한것은 아니므로 scope을 runetime으로 지정

h2-console 설정

: 브라우저에서 h2-console 화면을 통해 기본적인 데이터베이스 관리 및 쿼리 실행을 할 수 있음

  • application.yml 설정
    spring:
        h2:
          console:
            enabled: true
             path: /h2-console
    • path 부분에 입력한 경로로 브라우저에서 접근 가능
  • spring security 설정
    @Override
    public void configure(WebSecurity web) {
      web.ignoring().antMatchers("/assets/**", "/h2-console/**");
    }

DataSource 설정 추가

  • 관련 의존성 추가

    • spring-boot-starter-jdbc : spring-jdbc
    • HikariCP : 데이터베이스 커넥션 풀
    • log4jdbc-remix : JDBC 쿼리 및 ResultSet 로깅
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    
    <dependency>
      <groupId>com.zaxxer</groupId>
      <artifactId>HikariCP</artifactId>
      <version>4.0.3</version>
    </dependency>
    
    <dependency>
      <groupId>org.lazyluke</groupId>
      <artifactId>log4jdbc-remix</artifactId>
      <version>0.2.7</version>
    </dependency>
  • HikariCP 기반 DataSource 설정

    spring:
    	datasource:
    	    driver-class-name: org.h2.Driver
    	    url: "jdbc:h2:mem:spring_security;MODE=MYSQL;DB_CLOSE_DELAY=-1"
    	    username: sa
    	    password:
    	    hikari:
    	      minimum-idle: 1
    	      maximum-pool-size: 5
    	      pool-name: H2_DB

H2 데이터베이스 초기화 설정

  • H2 데이터베이스는 어플리케이션을 재시작이 매번 초기화됨
  • 따라서, 어플리케이션 시작과 함께 데이터베이스에 테이블을 생성하고, 필요한 데이터를 입력해야 함
    spring:
    	sql:
        init:
          platform: h2
          schema-locations: classpath:sql/schema.sql
          data-locations: classpath:sql/data.sql
          encoding: UTF-8

log4jdbc-remix 적용

: 실행되는 SQL 및 ResultSet을 로깅

  • BeanPostProcessor 인터페이스를 구현하여, DataSource 객체를 Log4jdbcProxyDataSource 타입으로 Wrapping 처리

    @Component
    public class DataSourcePostProcessor implements BeanPostProcessor {
    
      @Override
      public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof DataSource && !(bean instanceof Log4jdbcProxyDataSource)) {
          return new Log4jdbcProxyDataSource((DataSource) bean);
        } else {
          return bean;
        }
      }
    
    }
  • logback 설정을 통해 선택적으로 로깅 처리

    <logger name="jdbc.sqltiming" level="INFO"/>
    <logger name="jdbc.audit" level="OFF"/>
    <logger name="jdbc.resultset" level="OFF"/>
    <logger name="jdbc.resultsettable" level="INFO"/>
    <logger name="jdbc.connection" level="OFF"/>
    <logger name="jdbc.sqlonly" level="OFF"/>

데이터베이스 기반 인증 처리

인증 처리

  • AuthenticationManager는 사용자의 인증 처치를 위한 작업을 AuthenticationProvider로 위임함
  • UsernamePasswordAuthenticationToken 타입의 인증 요청은 DaoAuthenticationProvider가 처리함

DaoAuthenticationProvider

  • 데이터베이스에서 사용자 인증 정보를 조회하는 작업을 UserDetailsService 인터페이스 구현체에 위임
  • UserDetailsService 인터페이스 구현체 중 InMemoryUserDetailsManager 클래스를 사용함
  • 따라서, UserDetailsService 인터페이스 구현체 중 JDBC를 지원하는 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl 구현체를 사용하면됨

JdbcDaoImpl

: 이름 그대로 JDBC를 통해 데이터베이스에서 사용자 인증 정보를 가져옴

  • JdbcDaoImpl 클래스에서 사용자 및 권한 조회를 위해 사용되는 기본 Query
    select username, password, enabled from users where username = ? -- 사용자 조회
    select username, authority from authorities where username = ?  -- 사용자의 권한 조회
  • schema.sql 에서 제공하는 기본 테이블 구조가 JdbcDaoImpl 클래스에서 사용하는 쿼리에 적합하게 된것은 우연의 일치가 아님 (의도적으로 그렇게 만듬)
  • 마지막으로 JdbcDaoImpl 객체를 Bean으로 등록하면 데이터베이스 기반 인증 처리가 완료됨
    • jdbcAuthentication 메소드는 UserDetailsService 인터페이스 구현체로 JdbcUserDetailsManager 객체를 등록함
    • JdbcUserDetailsManager 클래스는 JdbcDaoImpl 클래스를 상속하며, 보다 풍부한 기능을 제공함
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.jdbcAuthentication()
        .dataSource(dataSource)
      ;
    }

Refernece
1. 프로그래머스 백엔드 데브코스

profile
안녕하세요.

0개의 댓글