Spring Boot/STUDY

[Spring Boot] JPA 프로젝트 - Spring Security

코맹 2024. 6. 20. 16:51

build.gradle dependency 추가
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'

 

  • 빌드된 것을 확인
실행을 시켜보면...

콘솔창에 Using generated security password: 565cb989-58b9-4de6-8755-6bf62e5d9a22 라는 메세지가 뜸과 동시에 아래 화면이 나타난다.

 

id: user
pw: 565cb989-58b9-4de6-8755-6bf62e5d9a22
입력

  • 로그상의 UUID를 PW로 입력하면 페이지로 들어와지는 것을 확인할 수 있다
  • 로그에 찍히는 UUID 번호는 서버 실행시마다 계속 변경됨

따라서, 회원가입 필요!!😀

 

로그인을 하지 않고 페이지에 접속하기 위해 /sercurity/SecurityConfig.java 생성

package com.eunji.backboard.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

// 스프링시큐리티 핵심파일
@Configuration
@EnableWebSecurity
public class SecurityConfig {
  @Bean
  SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
    // http://localhost:8080/** 로그인하지 않고도 접근할 수 있는 권한을 주겠다.
    http.authorizeHttpRequests((atr) -> atr.requestMatchers(new AntPathRequestMatcher("/**"))
                                    .permitAll());

    return http.build();

  }
}

  • authoriazeRequests()가 version 7.0부터는 사용되지 않음
  • 따라서 authoriazeHttpRequests() 사용!
  • 이제 로그인하지 않고 홈페이지 접속이 가능하다

 

💥  http://localhost:8080/h2-console 페이지에 들어가지지 않는 문제 발생(403 에러)

  • Spring Security가 CSRF 위변조 공격을 막아줌
  • 따라서 H2 Database 페이지 접속이 안됐던 것
/sercurity/SecurityConfig.java 코드 추가
// CSRF 위변조 공격을 막는 부분 해제, 특정 URL은 CSRF 공격 리스트에서 제거
        .csrf((csrf) -> csrf.ignoringRequestMatchers(new AntPathRequestMatcher("/h2-console/**")))

 

  • .csrf((csrf) -> csrf.ignoringRequestMatchers(new AntPathRequestMatcher("/h2-console/**"))); 코드 추가

 

💥 이제는 연결이 되지 않는 문제 발생

아래 코드 추가
// h2-console 페이지가 frameset, frame으로 구성 CORS와 유사한 옵션 추가
        .headers((headers) -> headers
              .addHeaderWriter(new XFrameOptionsHeaderWriter(
                  XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN  // ignoringRequestMatchers 영역에 있는 프레임이니까 해제해줘
      )));

 

SecurityConfig.java 전체 코드
package com.eunji.backboard.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

// 스프링시큐리티 핵심파일
@Configuration
@EnableWebSecurity
public class SecurityConfig {
  @Bean
  SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
    // http://localhost:8080/** 로그인하지 않고도 접근할 수 있는 권한을 주겠다.
    http
        .authorizeHttpRequests((atr) -> atr.requestMatchers(new AntPathRequestMatcher("/**")).permitAll())

        // CSRF 위변조 공격을 막는 부분 해제, 특정 URL은 CSRF 공격 리스트에서 제거
        .csrf((csrf) -> csrf.ignoringRequestMatchers(new AntPathRequestMatcher("/h2-console/**")))
        // h2-console 페이지가 frameset, frame으로 구성 CORS와 유사한 옵션 추가
        .headers((headers) -> headers
              .addHeaderWriter(new XFrameOptionsHeaderWriter(
                  XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN  // ignoringRequestMatchers 영역에 있는 프레임이니까 해제해줘
              )));

    return http.build();

  }
}

 


h2에서 Oracle로 변경

 

application.properties
## H2 설정 - 내가 개발할 때만 쓰는 형태 추천
# spring.h2.console.enabled=true
# spring.h2.console.path=/h2-console
# spring.datasource.url=jdbc:h2:~/local
# spring.datasource.driver-class-name=org.h2.Driver
# spring.datasource.username=sa
# spring.datasource.password=

## JPA 설정
# spring.jpa.database=h2
spring.jpa.show-sql=true
# spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
### ddl-auto 자동으로 테이블을 만들어주는 기능
### 데이터베이스 관리 정책 >> 실제 운영하는 서버에서는 validate(1), update(2)
### create: application 실행시마다 새로 생성, 최초 개발시
### create-drop: application 실행시 생성, 종료시 드랍. 사용 비추천
### update: 최초 한번만, 변경사항이 있으면 반영, 계속 개발시
### validate: DB테이블과 엔티티 클래스가 일치하는지 검증만, 운영시
### none(default) - 사용 비추천
spring.jpa.hibernate.ddl-auto=update
  • H2설정 부분과 JPA 설정에서 h2 부분 주석 처리
## Oracle 설정 - 운영DB
spring.datasource.url=jdbc:oracle:thin:@localhost:11521:FREE
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.username=PKNUSB
spring.datasource.password=pknu_p@ss

spring.jpa.database=oracle
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.OracleDialect
  • application.properties에 Oracle 관련 설정 추가
application.properties 전체코드
spring.application.name=backboard

## 포트 설정 8080은 기본
server.port=8080

## 로그 색상
spring.output.ansi.enabled=always

## 수정사항 저정시 자동재빌드
spring.devtools.livereload.enabled=true
spring.devtools.restart.enabled=true

## 로그레벨 설정
logging.level.org.springframework=info
logging.level.com.eunji=debug

## H2 설정 - 내가 개발할 때만 쓰는 형태 추천
# spring.h2.console.enabled=true
# spring.h2.console.path=/h2-console
# spring.datasource.url=jdbc:h2:~/local
# spring.datasource.driver-class-name=org.h2.Driver
# spring.datasource.username=sa
# spring.datasource.password=

## Oracle 설정 - 운영DB
spring.datasource.url=jdbc:oracle:thin:@localhost:11521:FREE
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.username=PKNUSB
spring.datasource.password=pknu_p@ss

## JPA 설정
# spring.jpa.database=h2
spring.jpa.database=oracle
spring.jpa.show-sql=true
# spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.OracleDialect
### ddl-auto 자동으로 테이블을 만들어주는 기능
### 데이터베이스 관리 정책 >> 실제 운영하는 서버에서는 validate(1), update(2)
### create: application 실행시마다 새로 생성, 최초 개발시
### create-drop: application 실행시 생성, 종료시 드랍. 사용 비추천
### update: 최초 한번만, 변경사항이 있으면 반영, 계속 개발시
### validate: DB테이블과 엔티티 클래스가 일치하는지 검증만, 운영시
### none(default) - 사용 비추천
spring.jpa.hibernate.ddl-auto=update

 

build.gradle

 

runtimeOnly 'com.oracle.database.jdbc:ojdbc11'
  • ojdbc11이 들어가 있는지 확인

 

Test.java에서 더미 데이터 넣기
@SpringBootTest
public class BoardRepositoryTests {
  // JUnit 테스트
  @Autowired
  private BoardRepository boardRepository;

  @Autowired
  private BoardService boardService;

  @Test
  void testThreeHunderedBoards() {
    for (int i = 0; i < 400; i++) {
      this.boardService.setBoard(String.format("테스트 데이터 - [%03d]", i+1),
                                 "별 내용 없습니다.");
        }
      }
    }

 

DBeaver에서 BOARD 테이블 확인

  • 400개의 더미 데이터가 들어간 것을 확인할 수 있음