forked from baron/baron-sso
클라이언트 비활성화 및 로그인 차단 흐름 문서화
This commit is contained in:
91
docs/client_deactivation_flow.md
Normal file
91
docs/client_deactivation_flow.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# 클라이언트 비활성화(Deactivation) 및 로그인 차단 흐름
|
||||
|
||||
이 문서는 관리자가 개발자 포털(`devfront`)에서 특정 클라이언트(RP)를 비활성화했을 때, 해당 앱을 통한 인증 시도가 어떻게 차단되는지 상세 기술 흐름을 설명합니다.
|
||||
|
||||
## 1. 개요
|
||||
보안 사고나 점검 등의 사유로 특정 애플리케이션의 접근을 즉시 차단해야 할 경우, 관리자는 클라이언트 목록에서 '상태' 토글을 비활성화할 수 있습니다. 이 설정은 Ory Hydra의 클라이언트 메타데이터에 저장되며, Baron SSO 백엔드 인증 핸들러에서 이를 검증하여 차단을 수행합니다.
|
||||
|
||||
## 2. 전체 동작 흐름
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Admin as 관리자 (DevFront)
|
||||
participant Backend as 백엔드 (API)
|
||||
participant Hydra as Ory Hydra (OIDC 엔진)
|
||||
participant User as 사용자
|
||||
participant RP as 애플리케이션 (예: Gitea)
|
||||
|
||||
Note over Admin, Hydra: [1단계: 클라이언트 비활성화 설정]
|
||||
Admin->>Admin: 상태 스위치 클릭 (활성 -> 비활성)
|
||||
Admin->>Backend: PATCH /api/v1/dev/clients/{id}/status {status: "inactive"}
|
||||
Backend->>Hydra: PATCH /admin/clients/{id} (JSON Patch 형식)
|
||||
Hydra-->>Backend: 업데이트 완료 (metadata.status = "inactive")
|
||||
Backend-->>Admin: 성공 알림
|
||||
|
||||
Note over User, Backend: [2단계: 로그인 시도 및 차단]
|
||||
User->>RP: 로그인 시도 (Baron SSO 선택)
|
||||
RP->>Hydra: 인증 요청 (/oauth2/auth)
|
||||
Hydra->>User: 로그인 페이지로 리디렉션 (login_challenge 포함)
|
||||
User->>Backend: 아이디/비밀번호 입력 및 로그인 요청
|
||||
Backend->>Hydra: GetLoginRequest(challenge) 호출
|
||||
Hydra-->>Backend: 클라이언트 정보 응답 (Metadata 포함)
|
||||
|
||||
Note right of Backend: 비활성 체크 로직 작동
|
||||
Backend->>Backend: Metadata["status"] == "inactive" 확인
|
||||
|
||||
alt 비활성화 상태인 경우
|
||||
Backend-->>User: 403 Forbidden (비활성화된 앱 안내)
|
||||
Note over User: 로그인 프로세스 중단
|
||||
else 활성화 상태인 경우
|
||||
Backend->>Hydra: AcceptLoginRequest
|
||||
Hydra-->>User: 동의 화면 또는 RP로 리디렉션
|
||||
end
|
||||
```
|
||||
|
||||
## 3. 상세 구현 내용
|
||||
|
||||
### 3.1. 관리자 UI 및 상태 변경
|
||||
- **파일**: `devfront/src/features/clients/ClientsPage.tsx`
|
||||
- **함수**: `updateStatusMutation`
|
||||
- **로직**: 사용자가 스위치를 토글하면 `updateClientStatus` API를 호출합니다. 업데이트 중에는 중복 클릭을 방지하기 위해 스위치가 `disabled` 상태가 됩니다.
|
||||
|
||||
### 3.2. 백엔드 상태 업데이트 중계
|
||||
- **파일**: `backend/internal/handler/dev_handler.go`
|
||||
- **함수**: `UpdateClientStatus`
|
||||
- **로직**: 클라이언트 ID와 변경할 상태값을 받아 `service.HydraAdminService`의 `PatchClientStatus`를 호출합니다.
|
||||
- **파일**: `backend/internal/service/hydra_admin_service.go`
|
||||
- **함수**: `PatchClientStatus`
|
||||
- **로직**: Ory Hydra Admin API 규격에 맞춰 **JSON Patch(RFC 6902)** 형식을 생성합니다.
|
||||
```go
|
||||
payload := []map[string]interface{}{
|
||||
{"op": "replace", "path": "/metadata/status", "value": status},
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3. 인증 단계별 차단 검증 (핵심 보안 로직)
|
||||
백엔드는 OIDC 인증 흐름의 3가지 주요 진입점에서 클라이언트의 활성 상태를 매번 체크합니다.
|
||||
|
||||
#### 1) 수동 로그인 시 (`PasswordLogin`)
|
||||
- **파일**: `backend/internal/handler/auth_handler.go`
|
||||
- **로직**: 사용자가 직접 아이디/비밀번호를 입력했을 때, `login_challenge`가 있다면 Hydra에 해당 클라이언트 정보를 조회하여 `metadata.status`가 `inactive`인지 확인합니다.
|
||||
|
||||
#### 2) 자동 로그인 시 (`AcceptOidcLoginRequest`)
|
||||
- **파일**: `backend/internal/handler/auth_handler.go`
|
||||
- **로직**: 사용자가 이미 SSO 세션을 가지고 있어 자동으로 로그인이 진행될 때 호출됩니다. 승인(Accept)을 보내기 직전에 클라이언트 상태를 체크하여 차단합니다.
|
||||
|
||||
#### 3) 동의 화면 진입 시 (`GetConsentRequest`)
|
||||
- **파일**: `backend/internal/handler/auth_handler.go`
|
||||
- **로직**: 로그인 후 권한 동의 화면을 그리기 위해 정보를 가져오는 시점입니다. 비활성화된 앱이라면 정보를 반환하지 않고 에러를 발생시킵니다.
|
||||
|
||||
## 4. 예외 및 에러 처리
|
||||
- 클라이언트가 비활성화된 경우 백엔드는 `403 Forbidden` 상태 코드와 함께 `"The client application is disabled."` 메시지를 반환합니다.
|
||||
- 백엔드 로그에는 `slog.Warn`을 통해 `"Login rejected for inactive client"` 메시지가 기록되어 관리자가 시도 이력을 추적할 수 있습니다.
|
||||
|
||||
## 5. 확인 방법 (테스트 시나리오)
|
||||
1. `devfront`에서 특정 앱의 스위치를 끕니다.
|
||||
2. 해당 앱에서 로그인을 시도합니다.
|
||||
3. 이미 로그인된 상태여도 리디렉션 과정에서 "비활성화된 애플리케이션입니다"라는 안내와 함께 차단되는지 확인합니다.
|
||||
4. 백엔드 로그에서 차단 기록을 확인합니다:
|
||||
```bash
|
||||
docker compose logs -f backend | grep "inactive client"
|
||||
```
|
||||
Reference in New Issue
Block a user