Skip to content

Latest commit

 

History

History
179 lines (136 loc) · 8.55 KB

session02.md

File metadata and controls

179 lines (136 loc) · 8.55 KB

02. Security 설정, Data 설정

Security 설정

강의에서 사용하고 있는 버전은 Spring Boot 2.4.1이어서 SecurityConfig를 다음과 같이 작성하였습니다.

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/api/hello").permitAll()
                .anyRequest().authenticated();
    }
}

@EnableWebSecurity 애노테이션은 기본적인 웹 보안을 활성화하겠다는 의미입니다. 추가적인 설정을 위해 WebSecurityConfigurer를 implements 하거나 WebSecurityConfigurerAdapter를 extends 하는 방법이 있는데 강의에서는 WebSecurityConfigurerAdapter 사용하였습니다. configure 내에 있는 설정의 의미는 다음과 같습니다.

  • authorizeRequests() : HttpServletRequest를 사용하는 요청들에 대한 접근 제한을 설정하겠다는 의미
  • anyMatchers("/api/hello").permitAll() : 설정된 요청 URI는 인증 없이 접근을 허용하겠다(permitAll())는 의미
  • anyRequest().authenticated() : 나머지 요청에 대해서는 모두 인증을 받아야 함

그러나 Spring Boot 3.2.3에서는 WebSecurityConfigurerAdapterantMatchers가 deprecated 되었습니다. WebSecurityConfigurerAdapter을 extends 하여 사용하는 대신 SecurityFilterChain Bean을 사용합니다. 그리고 antMatchers 대신 requestMatchers를 사용하여 설정합니다.

Spring Security 5.4 introduced the capability to publish a SecurityFilterChain bean instead of extending WebSecurityConfigurerAdapter. In 6.0, WebSecurityConfigurerAdapter is removed. To prepare for this change, you can replace constructs like:

In Spring Security 5.8, the antMatchers, mvcMatchers, and regexMatchers methods were deprecated in favor of new requestMatchers methods. The new requestMatchers methods were added to authorizeHttpRequests, authorizeRequests, CSRF configuration, WebSecurityCustomizer and any other places that had the specialized RequestMatcher methods. The deprecated methods are removed in Spring Security 6.

더 상세한 내용은 공식 문서를 참고하시길 바랍니다.

변경된 내용을 바탕으로 SecurityConfig를 작성하면 다음과 같습니다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .authorizeHttpRequests(auth ->
                        auth
                                .requestMatchers("/api/hello").permitAll()
                                .anyRequest().authenticated())
                .build();
    }
}

이제 프로젝트 실행 후 /api/hello 요청을 하여 인증 없이 동작하는지 확인해보겠습니다. 그러면 다음과 같이 정상적으로 응답이 내려오는 것을 확인할 수 있습니다.

image

Datasource, JPA 설정

이번에는 Datasource와 JPA를 설정하도록 하겠습니다. application.yml 파일에 다음과 같이 설정을 작성합니다.

spring:
  application:
    name: spring-boot-jwt-tutorial

  h2:
    console:
      enabled: true

  datasource:
    url: jdbc:h2:mem:test
    driver-class-name: org.h2.Driver
    username: sa
    password:

  jpa:
    database-platform: org.hibernate.dialect.H2Dialect
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        format_sql: true
        show_sql: true

logging:
  level:
    practice: DEBUG

H2 인메모리 DB를 사용하도록 Datasource 를 설정하고, JPA 관련 기본 설정도 하였습니다. JPA 설정 중 ddl-auto: create-drop은 Session 실행 시 스키마를 생성하고, 종료 시 삭제하는 설정입니다. ddl-auto의 다른 설정은 다음과 같으며, 실제 배포 시에는 validatenone을 사용합니다.

  • create : SessionFactory 시작 시 스키마를 삭제하고 다시 생성
  • update : SessionFactory에 연결된 DB와 비교하여 추가된 항목이 있는 경우 추가. 만약 같은 변수 명이 존재하면 오류 발생
  • validate : SessionFactory 시작 시 객체 구성과 스키마가 다르면 예외 발생
  • none : 아무것도 안함

format_sqlshow_sql은 console에서 SQL을 보기 위해 설정한 것이며, logging level은 DEBUG로 설정하였습니다.

Entity 생성 및 Data 설정

강의를 참고하여 Authority라고 하는 권한에 대한 Entity와 User Entity를 생성합니다. 이 때, User와 Authority는 ManyToMany 관계입니다.

ddl-auto: create-drop이라고 설정되어 있어 매번 새로 테이블이 생성되므로, 초기 데이터를 자동으로 추가하도록 구성해보겠습니다.

insert into "user" (username, password, nickname, activated) values ('admin', '$2a$08$lDnHPz7eUkSi6ao14Twuau08mzhWrL4kyZGGU5xfiGALO/Vxd5DOi', 'admin', 1);
insert into "user" (username, password, nickname, activated) values ('user', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 'user', 1);

insert into authority (authority_name) values ('ROLE_USER');
insert into authority (authority_name) values ('ROLE_ADMIN');

insert into user_authority (user_id, authority_name) values (1, 'ROLE_USER');
insert into user_authority (user_id, authority_name) values (1, 'ROLE_ADMIN');
insert into user_authority (user_id, authority_name) values (2, 'ROLE_USER');

그 다음 data.sql이 정상 실행되도록 application.ymljpa.defer-datasource-initialization: true 설정을 추가해줍니다. 해당 설정을 추가하지 않으면 Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource라는 에러를 마주하게 됩니다.

  jpa:
    defer-datasource-initialization: true

H2 Console 결과 확인

H2 Console에 접속하기 위해서는 SecurityConfig 수정이 필요합니다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(auth ->
                        auth
                                .requestMatchers("/api/hello").permitAll()
                                .requestMatchers(PathRequest.toH2Console()).permitAll()
                                .anyRequest().authenticated())
                .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin))
                .build();
    }
}
  • csrf(AbstractHttpConfigurer::disable) : csrf 비활성화 (H2 Console은 CSRF에 대응되지 않는 페이지)
  • requestMatchers(PathRequest.toH2Console()).permitAll() : PathRequest.toH2Console()을 사용하여 자동으로 올바른 경로를 찾아주도록 설정
  • headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)) : H2 Console이 정상 동작하기 위해서는 같은 Origin에 대해 허용 필요

그 다음 프로젝트를 실행해보면 console에 data.sql에 작성한 SQL문이 뜨는 것을 확인할 수 있습니다.

image

실제로 H2 Console(http://localhost:8080/h2-console)에 접속해보면, 다음과 같은 로그인 화면이 뜹니다.

image

여기서 connect 버튼을 클릭하면, 다음과 같이 테이블이 정상적으로 생성된 것을 확인할 수 있습니다.

image

본 게시글은 Spring Boot JWT Tutorial 강의를 참고하여 작성되었습니다.

상세한 내용이 궁금하시다면 강의 수강을 추천해 드립니다.

추가로 참고한 내용