Spring Security 프로젝트 설정 1 - DB연결과 JPA 설정
✒️ 2025-05-28 14:19 내용 수정
-
가이드 영상 : Amigoscode's Spring Boot 3 + Spring Security 6 - JWT Authentication and Authorisation
-
Spring Security의 가이드 영상을 찾아보던 중 위 영상이 도움이 되어 영상 내용을 직접 따라하며 내용을 정리하였다.
- 이전에 Spring Security 5.x 버전 영상을 참고했다가 Spring Security Config에서 많은 부분이 달라져서 Spring Security 6.x 버전 영상을 다시 찾아 정리했다.
-
SpringSecurity 프로젝트 설정 목록
- Spring Security 기본 사용자 추가 및 테스트
- Spring Security 프로젝트 설정 1 - DB연결과 JPA 설정
- Spring Security 프로젝트 설정 2 - JwtService와 Filter 설정
- Spring Security 프로젝트 설정 3 - Security Config
- Spring Security 프로젝트 설정 4 - Authentication Service와 Controller
- Spring Security 프로젝트 설정 5 - Security CORS 설정
- Spring Security 프로젝트 설정 6 - JWT Refresh Token 생성 및 저장
- Spring Security 프로젝트 설정 7 - JWT Refresh Token 재발급
- Spring Security 프로젝트 설정 8 - JWT 클라이언트 저장
- Spring Security 프로젝트 설정 9 - JWT 로그아웃
- Spring Security 프로젝트 설정 10 - 권한 설정
흐름
- 클라이언트로부터 요청이 들어오면
SecurityFilterChain에서 요청을 받는다. Filter중에JwtAuthenticationFilter는 JWT에 관련된 토큰의 유효성을 검증하는 역할을 하며, 요청에서 같이 온 JWT를 확인하여 사용자 정보나 데이터를 추출한다.- 만약 JWT가 없으면
403응답을 전송한다.
- 만약 JWT가 없으면
- 추출한 정보를 가지고
JwtAuthenticationFilter는UserDetailsService를 호출하여 DB로부터 사용자 정보를 가져온다. - DB로부터 온 정보에서 사용자 정보가 존재하지 않으면
403응답을 전송하고, 존재한다면 JWT 유효성 검사를 진행한다.- JWT가 유효하지 않으면(만료되거나 대상 불일치 등)
403응답을 전송한다.
- JWT가 유효하지 않으면(만료되거나 대상 불일치 등)
- JWT가 유효하다면
SecurityContextHolder에 정보를 업데이트하고,DispatcherServlet을 호출하여Controller로 요청을 전달하고,Controller는 사용자가 요청한 정보를 반환한다.

프로젝트 기본 설정
- https://start.spring.io/ 에서 프로젝트의 설정 및 Dependencies를 설정한다.
| 항목 | 설정 |
|---|---|
| Project | Gradle-Groovy |
| Language | Java |
| Spring boot | 3.3.5 |
| Package | Jar |
| Java | 17 |
| Dependencies | Spring Security 6.3.4 |
Spring Data JPA 3.3.5 |
|
Spring Web 3.3.5 |
|
MySQL Driver 6.1.14(DB 연결) |
|
Spring Boot DevTools |
|
Lombok 1.18.34 |
- JWT 생성 및 조작에 관한 메소드를 사용하기 위해
build.gradle에 JWT 의존성을 추가한다.- 참고 자료 : https://www.devyummi.com/page?id=668d013f958b03acd4c248e5
- 최신 버전은
0.12.3버전이나, 가이드 영상 기준으론0.11.5버전을 사용하였고, 버전에 따라 메소드가 많이 상이하다는 참고 자료 내용이 있어 강의 영상과 같은 버전을 사용하였다.
dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
}
DB 연결과 JPA 설정(MySQL)
- MySQL 기준으로 작성하였으며, DB 연결 설정을 위해
application.properties에 Spring datasource와 JPA hibernate 설정을 추가한다.
# 애플리케이션 이름
spring.application.name=security
# port 설정
server.port=9000
# MySQL 드라이버 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 연결할 DB 주소. 마지막은 db 이름이나 schema 이름을 입력한다.
spring.datasource.url=jdbc:mysql://localhost:3306/userservice
# DB 사용자 이름 및 비밀번호
spring.datasource.username=root
spring.datasource.password=password
# hibernate ddl 설정 - create면 새로 생성
spring.jpa.hibernate.ddl-auto=create
# sql을 콘솔에 표시할지 여부
spring.jpa.show-sql=true
# Hibernate가 DB에 맞게 SQL을 생성하고 최적화(방언 설정)
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
# Hibernate가 실행하는 SQL 쿼리를 보기 쉽도록 포맷팅
spring.jpa.properties.hibernate.format_sql=true
# Spring Security에 사용자와 비밀번호 추가
spring.security.user.name=user
spring.security.user.password=1234
application.yml의 경우
# port
server:
port: 9000
# MySQL
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
# DB 주소
url: jdbc:mysql://localhost:3306/userservice
# DB 사용자 정보
username: root
password: password
# hibernate ddl 설정 - create면 새로 생성
jpa:
hibernate:
ddl-auto: create-drop
# sql을 콘솔에 표시할지 여부
show-sql: true
properties:
hibernate:
# Hibernate가 DB에 맞게 SQL을 생성하고 최적화(방언 설정)
dialect: org.hibernate.dialect.MySQLDialect
# Hibernate가 실행하는 SQL 쿼리를 보기 쉽도록 포맷팅
format_sql: true
# Spring Security에 사용자와 비밀번호 추가
security:
user:
name: user
password: 1234
Entity와 Repository 설정
src/main/java/package에user패키지를 만들고,User클래스를 생성한다.User클래스는UserDetails인터페이스의 메소드를 사용하기 위해 이를 구현한다.- Spring Security Architecture#Architecture Components 참고.
- 이미
UserDetails를 구현한org.springframework.security.core.userdetails.User클래스도 존재하기 때문에UserDetails를 직접 구현해서 사용할지,org.springframework.security.core.userdetails.User클래스를 상속 받아 사용할지 선택할 수 있다.
package com.example.security.user;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
@Data
@Entity // Entity임을 명시
@Builder // for Object building
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "user") // DB에 테이블 이름 지정
public class User implements UserDetails {
// Spring Security의 UserDetails
@Id // id로 지정
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstname;
private String lastname;
private String email;
private String password;
@Enumerated(EnumType.STRING) // Role이 Enum임을 명시
// EnumType.STRING은 String value 순으로 정렬
private Role role;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// 역할 List를 반환
return List.of(new SimpleGrantedAuthority(role.name()));
}
@Override
public String getUsername() {
return email;
}
// 계정 만료 및 잠김에 대해선 테스트를 위해 true로 설정
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
// UserDetails에 있는 getPassword()를 오버라이드
// 현재 클래스의 password를 반환하도록 설정
@Override
public String getPassword() {
return password;
}
}
Roleenum
package com.example.security.user;
public enum Role {
USER, ADMIN
}
- 같은 패키지에
UserRepository인터페이스를 생성하고,JpaRepository를 상속 받는다.- JPA(Java Persistence API) 참고.
Optional: 값이 있을수도 없을 수도 있는 null로 인한NullPointerException을 방지할 수 있는 Java 8 클래스이다.
package com.example.security.user;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
// 이메일로 사용자 조회
// Optional : 값이 있을수도 없을 수도 있는 null로 인한
// NullPointerException을 방지할 수 있는 Java 8 클래스
Optional<User> findByEmail(String email);
}