Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions keyword/chapter08/keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
- Spring Security가 무엇인가?

### Spring Security란?

- **인증, 권한 관리 그리고 데이터 보호 기능을 포함**하여 **웹 개발 과정에서 필수적인 사용자 관리 기능을 구현하는데 도움**을 주는 **Spring의 강력한 프레임워크**
- 일반적으로 개발 시 가장 먼저 작업하는 부분이 사용자 관리 부분으로, 회원가입부터 로그인, 로그아웃, 세션 관리, 권한 관리까지 다양한 인가 & 보안 기능은 개발자에게 많은 시간을 요구
- Spring Security는 이러한 요구사항을 효과적으로 지원하여 개발자들이 보안 관련 기능을 효율적이고 신속하게 구현할 수 있도록 도와줌

### 왜 사용하는가?

- Spring의 생태계에서 보안에 필요한 기능들을 제공하기 때문
- 프레임워크를 사용하지 않고 코드를 직접 작성할 경우 Spring에서 추구하는 IoC/DI 패턴과 같은 확장 패턴을 염두에 두고 인증/인가 부분을 직접 개발하기는 쉽지 않은데, Spring Security에서 이와 같은 기능들을 제공해 주기 때문에 개발 작업 효율을 높일 수 있음

### 동작 흐름

📌 Spring과의 상호작용 (외부 흐름)

1. 사용자의 요청이 서버로 들어옴
2. **Authentication Filter**가 요청을 가로채고 Authentication Manager로 위임
3. Authentication Manager는 등록된 **Authentication Provider**를 조회하며 인증을 요구
4. Authentication Provider가 실제 데이터를 조회하여 **UserDetails** 결과를 돌려줌
5. 결과는 **SecurityContextHolder**에 저장되어 Spring Controller에서 사용할 수 있게 됨

📌 내부 인증 처리 흐름

1. 사용자가 자격 증명 정보를 제출하면, **AbstractAuthenticationProcessingFilter**가 Authentication 객체를 생성
2. 해당 객체가 **AuthenticationManager**에게 전달
3. **인증 실패 시**: SecurityContextHolder가 초기화되고 `AuthenticationFailureHandler`가 실행
4. **인증 성공 시**: `SessionAuthenticationStrategy`가 새 로그인을 알리고, Authentication이 SecurityContextHolder에 저장되며 로그인 세션 정보가 HttpSession에 저장
- 인증(Authentication)vs 인가(Authorization)

### 인증(Authentication)

- 사용자가 주장하는 신원을 검증하는 단계
- 비밀번호나 생체 인식 등을 사용하여 이루어짐
- “당신이 누구인가”라는 질문에 대한 대답

### 인증 방법 3단계

- 인증 프로세스는 사용자가 신원을 증명하는 과정으로, 대체로 세 단계로 나뉨
1. **사용자 식별**: 사용자가 누구인지 확인하는 단계로, 보통 사용자 이름이나 이메일 주소를 제공
- 시스템의 접근 조건을 결정하는 데 필요
2. **자격 증명 확인:** 사용자는 비밀번호나 생체 인식 정보를 입력하여 자격 증명이 검증.
- 보안의 핵심이며, 정확한 검증 기술이 필수적
3. **최종 검증:** 사용자가 입력한 정보와 시스템 저장 정보를 대조하여 확인
- OTP(일회용 비밀번호)를 통해 보안을 강화할 수 있으며, 사용자 신뢰를 높임

### 인가(Authorization)

- 인증된 사용자가 시스템 내에서 어떤 기능이나 데이터에 접근할 수 있는지를 결정
- “당신이 할 수 있는 일은 무엇이냐”라는 질문에 대한 대답
- 예를 들어, 관리자는 추가 자원에 접근할 수 있지만 일반 사용자는 그렇지 않음

### 인가 유형

- **역할 기반 인가:** 사용자의 역할에 따라 접근 권한이 부여됨
- **속성 기반 인가:** 사용자의 속성에 따라 접근 권한이 결정됨
- **정책 기반 인가:** 조직의 정책과 규칙에 따라 접근 권한을 설정
- Stateful vs Stateless

### Stateful — 세션(Session) 방식

- 서버에 추가 정보, 즉 현재 트랜잭션의 상태를 기록하고 다음 명령을 기다리는 방식
- ex) 로그인, 상품 주문 등
- **동작 흐름**
- Stateful은 쿠키를 기반으로 하지만, 클라이언트에 저장하는 쿠키와는 다르게 **서버에 저장하여 관리**
- 서버에서는 클라이언트를 구별하기 위해 각각의 **Session ID**를 클라이언트마다 부여하게 되며, 클라이언트가 종료되기 전까지 유지
- **동작 방식**
1. 클라이언트가 로그인 요청
2. 서버에서는 클라이언트에게 고유한 Session ID를 부여하고 세션 저장소에 저장한 후 클라이언트에게 발급
3. 클라이언트는 서버에서 발급받은 Session ID를 쿠키에 저장하게 되고, 요청을 보낼 때 마다 쿠키를 함께 보냄

```java
[클라이언트] [서버]
| |
|--- 로그인 요청 (ID/PW) ------->|
| |-- 세션 ID 생성 & 저장소 저장
|<-- 세션 ID 발급 (쿠키) --------|
| |
|--- 페이지 요청 + 쿠키 -------->|
| |-- 세션 저장소에서 ID 조회 & 검증
|<-- 응답 (로그인 유지) ---------|
```

- **장점**
- 서버가 세션을 직접 관리 → 강제 로그아웃 가능
- 민감한 정보가 서버에만 있어 보안성 높음
- **단점**
- 서버에서 관리되기 때문에 비교적 안전하지만, 세션 탈취(Session Hijacking) 공격에 취약할 수 있음
- 세션 탈취(Session Hijacking): 시스템에 접근할 적법한 사용자의 아이디와 패스워드를 모르는 상태에서, 공격 대상이 이미 시스템에 접속되어 세션이 연결되어 있는 상태를 가로채기하는 공격.

### Stateless — JWT 토큰 방식

- 서버 측 세션에서 상태가 추적되지 않는다는 의미
- **동작 흐름**
- JWT는 암호화된 정보를 담는 토큰이 아님
- 정보 자체에 대해서는 암호화하지 않고 그대로 Payload에 담되, 그것에 대한 유효성 여부(변조되었는지)를 서버 측에서 감지하기 위한 서버의 secret_key를 통한 암호화된 signature 정보를 담고 있음
- 토큰이 서버가 필요한 유저 정보를 담고 있으므로, 서버가 유저 정보를 직접 관리하고 있지 않아 stateless 토큰이라고 함

```java
[클라이언트] [서버]
| |
|--- 로그인 요청 (ID/PW) ---------->|
| |-- 유저 정보 확인 후 JWT 생성
|<-- JWT 토큰 발급 ----------------|
| (Header.Payload.Signature) |
| |
|--- 요청 + JWT 토큰 (헤더에 첨부)->|
| |-- Signature 검증만 수행
|<-- 응답 (로그인 유지) -----------|
```

- **장점**
- 인증과 관련된 정보를 서버에 저장하지 않아도 되고, 수평적 확장이 용이한 점 때문에 토큰 기반 인증이 선호
- **단점**
- 서버가 기억하지 않는다는 것은, 반대로 말하면 “서버가 통제할 수 없다”는 뜻이기에 보안의 약점
- 세션 방식에서는 해커가 세션 ID를 훔쳐가도, 서버 관리자가 해당 세션을 삭제하면(강제 로그아웃) 방어가 가능했지만, JWT는 한 번 발급되어 클라이언트에게 넘어간 토큰을 서버가 통제하기 어려움