| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- 개발
- linux
- springboot
- html
- 자바
- Eclipse
- css
- 노개북
- 보안
- 안철수
- GraphQL
- js
- 안드로이드 개발
- 안드로이드
- 탐지기법
- java
- 코틀린
- Android 4.1
- gradle
- Android
- ActiveX
- 리눅스
- JavaScript
- kotlin
- 구글
- C++
- build.gradle
- hcj
- 하버드
- Today
- Total
꿈소년의 개발 이야기
[스프링 부트 개발자 온보딩 가이드 스터디] Chapter 06 Minilog에 인증 기능 추가하기 본문
[스프링 부트 개발자 온보딩 가이드 스터디] Chapter 06 Minilog에 인증 기능 추가하기
fogthegreat 2026. 4. 5. 21:25DAY 7
🔖 오늘 읽은 범위 :
🌱공부 내용: Chapter 06 Minilog에 인증 기능 추가하기
👢쪽수: p.219-p.290
- 목표: Minilog API 에 안전한 인증 시스템 추가
- 기능 요구사항
- JWT(JSON Web Token)의 생성 및 검증 기능 추가.
- JWT에 사용자의 User Name, ID, 발급 시간, 만료 시간 포함.
- AUTHOR와 ADMIN 두 가지 권한 부여 기능 제공.
- AUTHOR: 게시글 작성 및 조회 권한.
- ADMIN: 게시글 관리 및 사용자 관리(수정, 삭제) 권한.
- 각 컨트롤러의 엔드포인트에 JWT 인증 기능 추가. 즉, 인가되지 않은 사용자는 엔드포인트에 접근하지 못하도록 차단.
- JWT(JSON Web Token)의 생성 및 검증 기능 추가.
- 구현 요구사항
- 로그인 및 Swagger 페이지를 제외한 모든 엔드포인트는 인증을 필수적으로 요구.
- User ID를 입력 받는 기존 컨트롤러 및 DTO를 수정하여, JWT에 포함된 식별자를 사용하도록 변경.
JWT 인증 이해하기
주요 인증 기법
- 인증 Authentication: 사용자와 시스템 간 신뢰를 형성. 시스템이 사용자로부터 받은 정보를 바탕으로 요청자가 실제인지 확인하는 데 목적이 있음.
세션 기반 인증
- 사용자가 인증에 성공 → 서버 세션 ID 생성 → 클라이언트 쿠키에 저장하는 방식.
- 클라이언트 요청 ⇒ 세션 ID를 전송해서 인증 상태를 유지한다.
- 장점: 구현이 간단하다. 많이 사용된다. 세션 정보가 서버에 저장되어 보안성이 높다.
- 단점: 서버가 상태를 유지해야 하는 부담이 있다. 확장성이 낮다. 분산 시스템 환경에서는 서버 간 세션 동기화가 필요하다.
토큰 기반 인증
- 서버가 사용자를 인증 → JWT 와 같은 토큰을 생성하여 클라이언트에 반환하는 방식.
- 서버는 세션 정보를 유지하지 않는다.
- 클라이언트는 발급 받은 토큰을 서버 요청에 함께 보내 인증을 수행한다.
- 서버는 클라이언트가 요청에 같이 담아 보내온 토큰이 유효한지 검사한다. 유효하지 않으면 403 에러 등을 반환한다.
- 장점: 여러 서버로 부하를 분산하기에도 유리하다.
- 단점: 토큰이 유출되면 제3자가 해당 토큰을 이용해 시스템에 접근이 가능하다.
OAuth 2.0
- 제3자 앱이 사용자의 리소스에 접근할 수 있도록 권한을 부여하는 인증 방식.
- 사용자가 앱에 로그인 → 앱은 OAuth 제공자로부터 접근 토큰을 받음. → 사용자 리소스에 접근한다.
- 장점: 제3자 인증 서비스와 쉽게 통합할 수 있다. 자원 소유자의 명시적인 동의가 필요하다.
- 단점: 구현이 복잡하다. 부가적인 네트워크 호출이 필요해서 속도가 느리다.
기타 인증
- 생체 인증, WebAuthn(FIDO2), SMS OTP(One Time Password), 이메일 OTP, SSO(Single Sign-On) 등.
Why JWT?
- 과거에는 대부분의 웹 애플리케이션이 세션 기반 인증을 했었음.
- 단일 서버에서는 간단하고 효과적임. 서버 인증 상태를 유지해야 해서 확장성이 낮음.
- 분산 환경에서는 서버 간 세션 동기화가 필요해서 어려움.
- MSA(마이크로 서비스 아키텍처) 구조에서는 불리한 방식임.
- JWT 기반 인증
- 서버 무상태성을 지원한다. ⇒ 인증 상태를 별도로 저장하지 않는다.
- JWT는 사용자 ID, 역할 Role, 권한 Permission, 만료 시간 Expiration 등 다양한 정보를 JSON 포맷에 담아 둔다.
- 표준화
- 분산 시스템, REST API 확산
- MSA, 서버리스 아키텍처
- 이질적인 시스템 간 인증과 권한 관리 통합에도 적절함.
- 인증 및 권한 부여 프레임워크들이 기본 토큰 형식으로 채택 하기도 함. OAuth 2.0, OpenID Connect
- 한계점
- 토큰 유출. 토큰을 안전하게 저장해야 함.
- 요청 헤더 처리 성능에 영향을 줌. 세션 ID보다 크기가 큼.
- 만료될 때 까지 토큰을 무효화 하기 어렵다.
- 대응
- HTTPS 사용.
- 만료 시간이 짧은
Access Token, 긴 수명의Refresh Token을 함께 사용을 권장. - 필요한 최소한의 정보만 포함해야 함.
JWT 구조와 메커니즘
- 인증과 권한 부여(Authorization)을 동시에 지원하는 무상태(Stateless) 방식의 토큰.
- 인증 단계: 사용자 신원 확인.
- 권한 부여 단계: 특정 리소스에 접근할 수 있는 권한인지 판단.
- 구성요소: 헤더(
Header), 페이로드(Payload), 시그니처(Signature)로 구성. Base64Url 로 인코딩 되고, 점(.) 을 기준으로 연결되어 하나의 문자열로 표현.- 헤더
- 토큰의 타입, 서명 알고리즘 정보 포함.
- 페이로드
- 토큰 데이터 = 클레임(Claim) 으로 구성.(키 - 값 쌍)
- 사용자 아이디, 역할, 토큰 만료 시간 등의 정보.
- 시그니처
- 헤더와 페이로드를 결합한 것에 대한 서명.
- 비밀 키를 사용해 생성된 서명.
- 토큰 무결성 보장.
- 헤더
JWT 인증 순서
- 사용자 이름 & 비밀번호 전송.
- 사용자 정보 확인.
- JWT 발급.
- JWT 포함 요청 전송.
- JWT 검증 및 권한 확인.
- 요청 처리 결과 반환.
스프링 시큐리티를 이용한 JWT 인증 기능 통합하기
- 스프링 보안 프레임워크 ⇒ 스프링 시큐리티 Spring Security
스프링 시큐리티 핵심 기능
- 인증(Authentication)
- 사용자 신원 확인 과정.
- 일반적으로 아이디와 비밀번호로 확인.
- 스프링 시큐리티 기본 인증 수단으로
UsernamePasswordAuthenticationFilter제공.
- 권한 부여(Authorization)
- 인증된 사용자가 애플리케이션 내에서 특정 작업을 수행할 수 있는 권한을 확인한다.
- 사용자 역할 및 권한 기반 접근 제어 수행.
- 보안 정책 구성 및 필터링(Policy & Filtering)
- HTTP 요청을 감시 → 인증된 요청만 애플리케이션으로 전달.
- CSRF 방지, 세션 관리, URL 접근 제어 등등.
스프링 시큐리티 주요 구성 요소
SecurityFilterChain
- HTTP 요청에 대한 게이트 키퍼 역할.
- 여러 보안 필터가 연결되어 있음. 필터를 통과시키며, 인증 및 인가 과정을 수행한다.
- 필터들은 개발자가 직접 정의하거나 설정을 통해 등록할 수 있다.
- 필터 처리는 순차적으로 진행된다.
UsernamePasswordAuthenticationFilter: 로그인 요청에서 사용자 이름과 비밀번호를 검증.JwtRequestFilter: 요청 헤더의 JWT를 해석하여 사용자를 인증한다.- 요청이 통과되지 못하면, 나머지 필터 실행을 중단 &
401(Unauthorized)or403(Forbidden)응답 반환 및 접근을 차단.
Authentication
- 사용자 인증 정보를 담는 객체.
- 주요 필드
principal: 인증된 사용자 ID 또는 주요 정보credentials: 인증에 사용된 비밀번호 및 인증 토큰,authorities: 사용자의 권한 목록.
SecurityContext
- 현재 요청 인증 정보를 저장하는 컨텍스트.
- 컨텍스트(
Context): 현재 요청의 보안 상태 및 인증 정보를 보관하는 환경 또는 저장소. - 스프링 시큐리티는 사용자 인증 성공 시, 생성된
Authentication객체를SecurityContext에 저장한다.SecurityContextHolder를 통해 전역적으로 접근할 수 있다. SecurityContextHolder- 일반적으로 스레드 로컬(
ThreadLocal)에SecurityContext를 보관한다. - 요청이 처리 되는 동안에는 애플리케이션 어느 위치에서나
SecurityContextHolder.getContext().getAuthentication()를 호출해서 현재 로그인한 사용자 인증 정보를 가져올 수 있다.
- 일반적으로 스레드 로컬(
AuthenticationManager, AuthenticationProvider
- 스프링 시큐리티에서 인증을 처리하는 핵심 인터페이스.
- 클라이언트 로그인 요청
→ AuthenticationManager 요청 수신 후 1개 이상의 AuthenticationProvider 에게 인증 위임.
→ AuthenticationProvider 는 스스로 처리할 수 있는 인증 방식(사용자 이름/비번, JWT, OAuth2 등)을 확인 한 후 인증 시도.
→ 인증 성공 후 Authentication 객체를 반환. - 직접 커스터마이징한 AuthenticationProvider를 구현하여 비표준 인증 로직(사내 인증 서버 연동, 토큰 검증, 다중 인증 등)을 구현 등록할 수 있다.
UserDetails, UserDetailsService
- UserDetails
- 사용자 계정 정보를 표현하기 위한 추상 인터페이스.
- username, password, authorities(권한 정보) 등의 필드를 포함한다.
- 인증 이후 “현재 로그인한 사용자”를 나타낸다.
- UserDetailsService
- UserDetails 객체를 데이터소스(데이터베이스, 외부 API 등)에서 조회하는 역할을 담당한다.
- 사용자 이름(username)을 기준으로 사용자 정보를 로드하고, 결과를 UserDetails 형태로 반환한다.
- UserDetailsService 를 통해 사용자를 조회한 뒤 입력된 비밀번호를 PasswordEncoder를 이용해 검증하며 인증을 완료한다.
- UserDetails
GrantedAuthority
- 사용자의 권한(Authority)을 나타내는 객체.
- 사용자가 애플리케이션 내에서 수행할 수 있는 행동의 범위를 결정한다.
- 인증 완료 후, UserDetails 객체의 getAuthorities() 메서드를 통해서 사용자에게 부여된 GrantedAuthority 목록을 확인할 수 있다.
- 이 권한 정보를 기반으로 특정 URL, 메서드 및 리소스에 대한 접근을 제어한다.
Configurer, DSL
DSL(Domain-Specific Language 도메인 특화 언어)
- HttpSecurity 를 통해 요청별 보안 정책을 선언적으로 정의할 수 있는 유연한 API.
Configurer
- DSL 구성을 가능하게 하는 설정 모듈 역할.
HttpSecurity
- 여러 Configurer를 체이닝 방식으로 연결하여 인증, 인가, 세션 관리, CSRF, CORS 등 다양한 보안 설정을 명시적으로 구성한다.
- 메서드 체이닝을 통해 자연어처럼 읽히는 DSL 스타일로 보안 정책을 작성한다.
httpSecurity .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests((requests) -> requests .requestMatchers("/api/v2/auth/login", "/swagger-ui/**", "/v3/api-docs/**").permitAll() .requestMatchers(HttpMethod.POST, "/api/v2/user").permitAll() .erquestMatchers(HttpMethod.DELETE, "/api/v2/user/{userId}").hasRole("ADMIN") .anyRequest().authenticated() );위 코드에 나온 메서드들처럼 호출되는 메서드는 각자의 Configurer를 내부적으로 호출하고, 시큐리티 필터 체인(SecurityFilterChain)에 설정을 추가하게 된다.
JwtUtil ⇒ 이 클래스는 제공되는 게 아니라 프로젝트에서 만들어서 사용하는 것임.
- JWT 생성, 검증, 클레임(Claims) 추출 등의 기능을 담당하는 유틸리티 클래스.
- 제공되는 기능
- 토큰 생성: 사용자 정보(username, roles 등)를 포함한 JWT 발급.
- 토큰 검증: 서명 유효성 및 만료 시간 검증.
- 클레임 추출: JWT 에서 사용자 이름, 권한 등 필요한 정보 추출.
- 토큰 관련 로직을 한 곳에 모아 관리한다.
- 인증 필터(JwtAuthenticationFilter 등등)에 대한 결합도를 낮추고, 테스트 및 유지 보수 하기 쉽게 한다.
- 토큰 생성, 검증 로직을 캡슐화해 인증 흐름과 분리하는 역할을 수행하는 것이 중요하다.
JWT 인증 과정
- JWT 검증.
- JwtRequestFilter: 요청 헤더에서 JWT를 추출하고 JwtUtil을 통해 검증한다.
- JwtUtil: 토큰의 유효성(서명, 만료 시간 등)을 확인한 후, 사용자 이름과 권한 정보를 추출한다.
- 검증 및 정보 추출 후 이 기반으로 Authentication 객체를 생성한다.
- Authentication 객체에는 사용자 권한 정보(GrantedAuthority)가 포함된다.
- 사용자 정보 로딩.
- AuthenticationManager: AuthenticationProvider를 통해 사용자 인증을 처리한다.
- 인증 과정에서 UserDetailsService 가 데이터베이스에서 사용자 정보를 로딩한다.
- 로딩된 정보를 바탕으로 UserDetails 객체가 생성되며, 이 객체에는 사용자 권한 정보(GrantedAuthority)도 포함된다.
- SecurityContext 에 인증 정보 저장.
- 인증 성공 후, 생성된 Authentication 객체는 SecurityContextHolder를 통해 현재 스레드의 SecurityContext 에 저장된다.
- 이 객체는 요청의 생명 주기 동안 유지 된다.
- 이후 권한 검증에 활용된다.
- 권한 검증.
- 요청된 URL에 대해 사용자 권한(GrantedAuthority)이 필요한 수준에 도달하는지 검사한다.
- 권한 확인 과정에서 SecurityContext 에 저장된 GrantedAuthority를 참조한다.
- 적합한 권한이 없는 경우, 403 Forbidden 응답을 반환한다.
- 권한 검사가 성공하면 요청이 컨트롤러로 전달되고 정상 처리 된다.
Project 설정
build.gradle 스프링 시큐리티 의존성 추가
dependencies {
...
// Spring Security, JWT
implementation 'org.springframework.boot:spring-boot-starter-security'
// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
// Spring Security Test
testImplementation 'org.springframework.security:spring-security-test'
// JWT Test
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
...
}
application.properties 에 비밀 키secret key 추가
jwt.secret=비밀키
⚠️ 비밀키 하드 코딩 금지 ⚠️
생성된 비밀키는 하드 코딩 하면 안된다.
비밀 관리 도구를 사용하여 안전하게 저장해야 한다.
- Onpremis HSM(Hardware Security Module)
- AWS Secrets Manager
- Azure Key Vault
- Google Cloud HSM
- jasypt
런타임에 비밀키를 가져올 수 있도록 설정해야 한다. 환경 변수 또는 비밀 관리 도구 API 를 활용해 애플리케이션이 키를 동적으로 불러오도록 구현할 수 있다.
관련 자료
AWS Secrets Manager
Azure Key Vault
Google Cloud HSM
Cloud HSM | Cloud Key Management Service | Google Cloud Documentation
인증 기능 구현
JWT 생성 및 검증 구현
- GrantedAuthority 상속하여 커스텀 GrantedAuthority 직접 정의하기.
- UserDetails, UserDetailsService 각각 상속한 커스텀 클래스 직접 정의하기.
- JWT 인증 처리 구현하기.
- SecurityFilterChain 설정하기.
- SecurityContext 보안 컨텍스트 설정하기.
- 엔드포인트에 대한 보안 설정하기.
GrantedAuthority 상속하여 커스텀 GrantedAuthority 직접 정의하기
- 커스텀 권한 로직 구현.
- 도메인 객체와의 통합.
- 확장성.
UserDetails, UserDetailsService 각각 상속한 커스텀 클래스 직접 정의하기
- UserDetails: 사용자 정보를 캡슐화 하는 인터페이스. 사용자명, 비밀번호, 권한 등의 정보를 제공한다.
- UserDetailsService: UserDetails 를 로드하는 서비스 인터페이스. 사용자 인증 시 필요한 사용자 정보를 제공한다.
JWT 인증 처리 구현
- JwtUtil: JWT 생성, 검증 유틸리티 클래스.
- JwtRequestFilter: JWT 활용하여 요청을 필터링 하는 필터.
- JwtAuthenticationEntryPoint: 인증 실패 할 경우에 대한 동작 정의.
- AuthenticationController: 로그인 요청 처리 컨트롤러.
JwtUtil
비밀키 관리
// application.properties 에 정의된 jwt.secret 값을 주입힌다. @Value("${jwt.secret}") private String jwt;
JwtRequestFilter
OncePerRequestFilter상속OncePerRequestFilter: 필터 로직이 요청 1번에 1번만 실행되도록 보장하는 안전 장치. 스프링 시큐리티 필터들의 공통 기반 클래스. 요청 하나당 각 필터가 한번씩만 실행되는 것을 보장 받는다.
- 토큰 추출 및 검증
- Authorization 헤더에서 JWT 추출.
- ‘Bearer’ 로 시작하는 경우에 대해 확인, 실제 토큰 값 얻기.
- 토큰에서 사용자명 추출하고, 토큰 유효성 검증.
- SecurityContext 설정
- 유효 토큰인 경우,
UsernamePasswordAuthenticationToken생성 후SecurityContextHolder에 설정함. - 이를 통해 인증된 사용자로 처리 된다.
- 애플리케이션 내에서 인증 정보를 사용할 수 있게 된다.
- 유효 토큰인 경우,
- 예외 처리 및 로그 메시지.
JwtAuthenticationEntryPoint
인증이 필요한 엔드포인트에 비인증 상태로 접근 할 경우 발생하는 예외를 처리한다.
AuthenticationEntryPoint인터페이스를 구현하여 인증 오류에 대한 응답을 처리한다.- 스프링 시큐리티에서 ‘미인증 사용자가 보호된 리소스에 접근할 경우, 인증 절차를 어떻게 시작할 것인지’를 정의하느 인터페이스.
인증이 필요한 요청이 인증 없이 들어 올 때, 가장 먼저 호출되는 진입점(entry point) 이다.
commence 메서드 구현
- 개시하다.
- 인증 절차를 개시하는 메서드.
- 인증 예외 발생 시 호출된다.
HTTP 상태 코드 401(Unathorized)와 함께 JSON 형식의 에러 메시지를 응답으로 보낸다.response.setStatus(HttpServletResponse.SC_UNATHORIZED)를 통해 상태 코드를 설정한다.
에러 메시지 설정.
Map을 사용해 응답 본문에 포함할 데이터를 구성한다.ObjectMapper를 사용해 맵을 JSON 문자열로 변환한다.
Content-Type 설정.
- reponse.setContentType(”application/json”) 을 통해 응답 컨텐츠 타입을 JSON 으로 지정한다.
- 클라이언트가 JSON 형식 에러 메시지를 적절하게 처리할 수 있도록 한다.
AuthenticationController
엔드포인트 설정
의존성 주입
인증 처리.
JWT 생성 및 변환
예외 처리.
응답 구조.
SecurityConfig
Bean 등록 처리.
PasswordEncoder: 사용자 암호 인코딩한다.
// PasswordEncoder 빈 설정하기 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }- 스프링 시큐리티는 비밀번호를 평문으로 저장하거나 비교하지 않는다.
- 항상 PasswordEncoder 를 빈으로 등록해 사용해야 한다. 빈이 등록되지 않으면 인증 과정에서 “No PasswordEncoder mapped for the id” 예외가 발생한다.
- BCryptPasswordEncoder: 비밀번호를 단방향 해시함수로 암호화한다. 같은 비밀번호도 매번 다른 해시 값을 생성한다. 무차별 대입 공격 또는 무작위 해시 공격에 강력한 보안성을 제공한다.
AuthenticationManager: 자격 증명을 검증한다.
// AuthenticationManager 빈 설정 @Bean public AuthenticationManager authenticationManagerBean( AuthenticationConfiguration configuration ) throws Exception { return configuration.getAuthenticationManager(); }- AuthenticationManager: 스프링 시큐리티 인증 과정을 총괄하는 핵심 인터페이스. 사용자 자격 증명(username 과 password)을 확인해 이를 기반으로 사용자가 애플리케이션에 접근할 수 있는지 여부를 결정한다.
- AuthenticationConfiguration 을 통해서 기본 제공되는 DaoAuthenticationProvider 를 사용한다.
- UserDetailsService 를 통해 사용자 정보를 로딩하고 PasswordEncoder 를 사용해서 비밀번호를 검증한다.
SecurityFilterChain: 보안 정책을 설정한다.
// SecurityFilterChain 빈 설정 @Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests( (requests) -> requests .requestMatchers("/api/v2/auth/login", "/swagger-ui/**", "v3/api-docs/**") .permitAll() // 사용자 생성, 조회는 인증 없이 가능하도록 조치. .requestMatchers(HttpMethod.POST, "/api/v2/user") .permitAll() .requestMatchers(HttpMethod.GET, "/api/v2/user/{userId}") .permitAll() // 사용자 삭제는 어드민 권한이 필요하도록 조치. .requestMatchers(HttpMethod.DELETE, "/api/v2/user/{userId}") .hasRole("ADMIN") .anyRequest() .authenticated()) .exceptionHandling( exceptionHandling -> exceptionHandling.authenticationEntryPoint(jwtAuthenticationEntryPoint)) .sessionManagement( sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); return httpSecurity.build(); }SecurityFilterChain 빈: 여러 보안 필터로 구성된 시큐리티 필터 체인 을 정의한다. HTTP 요청에 대해 이 필터 체인을 통과하고, 인증 및 인가 절차가 순차적으로 수행된다.
CSRF 보호 비활성화
csrf(AbstractHttpConfigurer::disable)를 통해서 CSRF 보호를 비활성화 한다.- REST API 는 일반적을 세션 기반이 아니며, CSRF 토큰을 사용하는 폼 요청이 없기 때문에 CSRF 공격의 노출 가능성이 낮다. 그래서 CSRF 보호 기능을 비활성화한다.
요청 인증 설정
- requestMatchers 를 통해 매칭되는 엔드포인트에 대해 필요한 인증 조치를 처리한다.
anyRequest().authenticated()를 통해서 나머지 엔드포인트에 대한 요청은 인증된 사용자만 접근하게 한다.
예외 처리 설정
exceptionHandling을 통해서 인증 실패 시JwtAuthenticationEntryPoint를 사용해서 처리하도록 설정한다.- 인증되지 않은 사용자가 보호된 리소스에 접근을 시도하면
JwtAuthenticationEntryPoint가 호출되어401 Unauthorized또는403 Forbidden응답을 반환한다.
세션 관리 설정
- JWT 를 사용하는 경우 서버 측 세션이 필요 없다.
- sessionManagement() 에서 SessionCreationPolicy.STATELESS 를 설정해, 서버가 세션을 생성하거나 유지하지 않도록 한다.
JWT 필터 추가
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)- JWT 기반 인증을 기존 인증 필터 보다 앞에서 수행하도록 설정한다.
- 요청 헤더의 토큰 검증이 먼저 이뤄지고, 유효한 토큰의 경우 사용자 정보가 SecurityContext에 설정되어 컨트롤러 접근 시 인증된 사용자로 인식된다.
엔티티와 DTO
엔티티
Role 필드 추가
@ElementCollection(fetch = FetchType.EAGER) @CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id")) @Enumerated(EnumType.STRING) @Column(name = "role") private Set<Role> roles;- 역할 정보를 데이터베이스 user_roles 테이블에 문자열로 저장하고, 즉시 로드할 수 있도록 설정한다.
비밀번호 자동 암호화하여 저장.
- lombok.Builder 를 제거하고, 커스텀 빌더 클래스 추가.
- 비밀번호 암호화 처리하고 제어할 수 있도록 커스텀 빌드 로직 구축.
컨트롤러
- @AuthenticationPrincipal
- JWT 를 통해 인증된 사용자 정보를 가져온다.
- UserDetails 객체를 통해서, 인증된 사용자 정보를 주입받는다.
- @PreAuthorize("hasRole('ADMIN')") // Only admins can delete users
- 관리자 권한(여기서는 ‘ADMIN’) 이 있는 사용자만 접근 가능하도록 설정한다.
- 메서드별로 세부적인 보안 설정을 추가할 수 있다.
- 마지막 JWT 인증 과정은 전체 도감이 필요해서 찾아봐야겠다.
'Do it 스터디! > 스프링 부트 개발자 온보딩 가이드 스터디!' 카테고리의 다른 글
| [스프링 부트 개발자 온보딩 가이드 스터디] Chapter 07 GraphQL 기반 마이크로블로그 API 서버 개발 (0) | 2026.04.05 |
|---|---|
| [스프링 부트 개발자 온보딩 가이드 스터디] 구글 OAuth2 로그인 기능과 JWT, 스프링 시큐리티 구현 (0) | 2026.04.05 |
| [스프링 부트 개발자 온보딩 가이드 스터디] 복잡한 실제 비즈니스 요구사항과 JPA 코드 구조 잡기 (0) | 2026.04.03 |
| [스프링 부트 개발자 온보딩 가이드 스터디] Chapter 05 고급 JPA 기반의 마이크로블로그 REST API 서버 개발 (0) | 2026.04.03 |
| [스프링 부트 개발자 온보딩 가이드 스터디] Chapter 04 JPA 기반의 To-Do 리스트 REST API 서버 개발 (0) | 2026.04.03 |
