# 클라이언트 비활성화(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" ```