뭐라도 끄적이는 BLOG

Spring Security Embedded H2 Database 사용 방법 본문

SpringFramework/Spring Security

Spring Security Embedded H2 Database 사용 방법

Drawhale 2023. 7. 8. 13:11

Embedded H2 Database

H2 Database는 자바기반의 오픈소스 RDBMS이다. H2 Database는 설치를 해서 사용할 수도 있지만 Database설치 없이 Application에 Database가 내장된 형태로 프로그램을 테스트 해볼 수 있다. 프로그램이 종료되면 데이터가 사라지기 때문에 간단한 테스트 용도에서만 사용한다.

implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'

H2 Database를 사용하기 위해서 위 2가지 의존성을 추가했다.

spring:
  h2:
    console:
      enabled: true
      path: /h2-console
  datasource:
    generate-unique-name: false

그리고 application.yml에 설정을 추가해 준다. enabled는 h2를 활성화 할것인가에 대한 여부를 나타낸다. path는h2 database에 접근할 수 있는 경로를 지정해 주는 부분이다. generate-unique-name은 false로 설정하면 기본 testdb데이터베이스를 생성고 true로 설정한다면 h2에서 랜덤한 값으로 database이름을 생성한다고 한다.(spring boot 3.1.1에서 테스트 해봤을땐 두가지 모두 testdb를 생성하였다.)

Configuration 변경점

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(authorize -> {
                    authorize.requestMatchers(HttpMethod.GET, "/").permitAll();
                    authorize.requestMatchers(HttpMethod.GET, "/user/**").hasRole("USER");
                    authorize.requestMatchers(HttpMethod.GET, "/admin/**").hasRole("ADMIN");
                    authorize.anyRequest().authenticated();
                })
                .csrf(AbstractHttpConfigurer::disable)
                .headers(header-> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
                .formLogin(withDefaults())
                .httpBasic(withDefaults());
        return http.build();
    }
    @Bean
    JdbcUserDetailsManager jdbcUserDetailsManager(DataSource dataSource) {
        return new JdbcUserDetailsManager(dataSource);
    }

    @Bean
    DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
                .build();
    }
}

Spring에 h2 database를 사용할 수 있도록 dataSource에 h2 database에 대한 정보를 넣고 Bean을 생성하였다.

securityFilterChain에 추가된 csrf 설정과 headers설정은 Embedded H2 database를 사용할때 추가해 줘야하는 설정이다. csrf설정을 disable하지 않으면 h2-console에 접근할 수 없고 header설정을 하지 않으면 접속은 가능하나 접속후 연결을 거부한다.

csrf disable 설정을 안했을때와 header frameOptionConfig disable 설정을 안했을때

해당 설정에는 h2-console에 대한 matcher가 authenticated로 연결되기 때문에 h2-console에 접속하려면 매번 로그인을 해줘야한다. 매번 로그인을 하지 않으려면 /가 포함된 matcher에 /h2-console/**을 추가하면 된다.

Application 시작시 데이터 추가

Embedded H2는 Application이 종료하면 데이터가 사라지는 Inmemory방식이다. 그렇기 때문에 테이스해볼 데이터를 매번 입력해 주어야 한다.

@SpringBootApplication
public class SpringSecurityTutorialApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringSecurityTutorialApplication.class, args);
    }

    @Bean
    CommandLineRunner commandLineRunner(JdbcUserDetailsManager jdbcUserDetailsManager, DataSource dataSource) {
        return arg -> {
            UserDetails admin = User.builder()
                    .username("admin")
                    .password("{noop}admin")
                    .roles("USER", "ADMIN")
                    .build();
            UserDetails user = User.builder()
                    .username("member")
                    .password("{noop}member")
                    .roles("USER")
                    .build();
            JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
            users.createUser(admin);
            users.createUser(user);
        };
    }
}

CommandLineRunner로 실행시 바로 User정보를 추가해 줄수 있다.

Embedded가 아닌 데이터베이스로 테스트해볼때 CommandLineRunner가 계속 남아있다면 2번째 실행때 primary key 중복이 발생해서 제대로 실행이 안될 수 도있다.

Application 실행

Application을 실행하면 Inmemory에 User들의 정보가들어가서 저장된 User정보로 로그인을 테이스 해볼 수 있으며 H2 console에 들어가서 저장된 User와 Role정보를 확인할 수 있다.

H2 console에 접속할 url, name 그리고 password는 Application 실행 console에서 확인해 볼 수 있다.

h2-console 접속시 보통 default로 값이 설정되어 있지만 다르게 입력되어 있을 수도 있으니 확인할 것.

※번외1:SQL로 사용자 정보 추가

CommandLineRunner를 이용해서 Java 코드로 사용자 정보를 넣어줄 수 도 있지만 resources에서 data.sql과 schema.sql로 정보를 넣어 줄 수도 있다. 우리는 Spring Security의 기본적인 부분만 살펴보고 있기 때문에 직접 Table설계를 하지 않았다. 그렇기 때문에 Spring Security에서 기본적으로 어떤 테이블을 이용하고 있는지 알아보고 테이블을 생성해 줘야할 필요가 있다.

기본으로 생성되는 H2 database테이블 정보와 다른 데이터베이스로 테스트해볼 때 어떤 테이블을 생성해야하는지 아래 링크에서 확인해 볼 수있다.

 

JDBC Authentication :: Spring Security

Spring Security provides default queries for JDBC-based authentication. This section provides the corresponding default schemas used with the default queries. You need to adjust the schema to match any customizations to the queries and the database dialect

docs.spring.io

현재 사용하고 있는 H2 Database는 아래와 같은 테이블을 사용하고 있다. 해당 정보를 resources/schema.sql에 추가해주면 된다.

create table users(
    username varchar(50) not null primary key,
    password varchar(500) not null,
    enabled boolean not null
);

create table authorities (
    username varchar(50) not null,
    authority varchar(50) not null,
    constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);

그리고 사용자 정보를 넣어주면 된다. 해당정보는 resources/data.sql에 추가해주면 된다.

insert into users(username, password, enabled)
values ( 'member', '{noop}member', true );
insert into users(username, password, enabled)
values ( 'admin', '{noop}admin', true );

insert into authorities(username, authority)
values ( 'member', 'ROLE_USER' );
insert into authorities(username, authority)
values ( 'admin', 'ROLE_USER' );
insert into authorities(username, authority)
values ( 'admin', 'ROLE_ADMIN' )

그리고 이전에 CommandLineRunner로 추가한 사용자 정보는 삭제하도록 하자.

schema.sql이나 data.sql 한쪽에 모든 쿼리를 넣어도 되지만 암묵적으로 schema.sql은 ddl, data.sql은 dml을 작성한다.

추가적으로 dataSorce Bean 생성 부분도 변경해 줘야한다. 

    @Bean
    DataSource dataSource() {
        return DataSourceBuilder.create()
                .driverClassName("org.h2.Driver")
                .url("jdbc:h2:mem:testdb")
                .username("sa")
                .password("")
                .build();
    }
반응형

'SpringFramework > Spring Security' 카테고리의 다른 글

Custom UserDetailsService & Custom User  (0) 2023.07.10
Multiple SecurityChain  (0) 2023.07.09
Spring Security OAuth(Google)  (0) 2023.07.09
Security Configuration  (0) 2023.07.07
Spring Security개요 및 Setup  (0) 2023.07.07