forked from baron/baron-sso
인증수단 세션 확인 추가
This commit is contained in:
77
docs/trouble-shooting/hydra-rp-consent-try.md
Normal file
77
docs/trouble-shooting/hydra-rp-consent-try.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Hydra RP Consent 시도 기록
|
||||
|
||||
## 목표
|
||||
- 샘플 RP(`52a597f0-5b06-4fcb-b804-93e88a56a75a`)와 사용자(`b24051@hanmaceng.co.kr`, Kratos ID: `22607c1b-bfbf-4a90-9505-36b348472e7a`) 사이에 Hydra consent 세션을 생성.
|
||||
|
||||
## 시도한 방법과 실패 원인
|
||||
|
||||
### 1) hydra 컨테이너 내부에서 `sh` 실행 후 스크립트 수행
|
||||
- 시도: `docker exec -i ory_hydra sh -lc '...'`
|
||||
- 실패: `sh`가 존재하지 않음 (Hydra 컨테이너가 distroless 이미지).
|
||||
- 원인: 쉘 바이너리 미포함.
|
||||
|
||||
### 2) `curlimages/curl` 컨테이너를 hydra 네트워크에 붙여서 consent 생성 흐름 수행
|
||||
- 시도 흐름:
|
||||
1. `/oauth2/auth` 호출로 `login_challenge` 획득
|
||||
2. Admin API로 `login_challenge` 수락
|
||||
3. `login_accept.redirect_to`(보통 `http://127.0.0.1:3000/...`)로 이동해 `consent_challenge` 추출
|
||||
- 실패: `login_accept.redirect_to`가 **consent app(127.0.0.1:3000)**로 향하는데, 해당 서비스가 떠 있지 않아 접근 불가.
|
||||
- 원인: consent app가 실행 중이 아니라 127.0.0.1:3000 접속 실패.
|
||||
|
||||
### 3) `login_accept.redirect_to`를 그대로 호출해 Location 헤더에서 consent_challenge 추출 시도
|
||||
- 실패: 위와 동일하게 consent app 경로를 직접 호출하게 되어 연결 실패.
|
||||
- 원인: consent app 미기동.
|
||||
|
||||
### 4) DCR(동적 클라이언트 등록) 시 metadata 포함 시도
|
||||
- 실패: `invalid_client_metadata` (DCR에서는 `metadata`를 설정할 수 없음)
|
||||
- 원인: Hydra DCR 정책 제한.
|
||||
|
||||
## 요약
|
||||
- **핵심 실패 원인**은 consent app(로그인/동의 UI)이 실행 중이 아니라서 redirect_to를 따라가면 접속이 불가능한 점.
|
||||
- distroless 이미지로 인해 `docker exec`로 쉘 스크립트를 바로 실행할 수 없음.
|
||||
|
||||
## 다음 시도(새 방식)
|
||||
- consent app로 직접 이동하지 않고, **Hydra public endpoint**에서 `login_verifier`를 이용해 `consent_challenge`를 추출한 뒤 Admin API로 수락.
|
||||
- 흐름:
|
||||
1. `/oauth2/auth` → `login_challenge`
|
||||
2. `/oauth2/auth/requests/login/accept` → `login_verifier`
|
||||
3. `/oauth2/auth?client_id=...&login_verifier=...` 호출 → Location 헤더에서 `consent_challenge` 추출
|
||||
4. `/oauth2/auth/requests/consent/accept` 호출
|
||||
|
||||
## 추가 시도 및 결과
|
||||
|
||||
### 5) login_verifier를 이용한 consent_challenge 생성 (public /oauth2/auth 호출)
|
||||
- 시도: `login_verifier`로 `/oauth2/auth?login_verifier=...` 호출 → Location에서 `consent_challenge` 추출 시도
|
||||
- 실패: `login_verifier has already been used` 또는 `invalid_client` 등으로 예제 redirect(`https://example.com/callback?...`) 에러 반환
|
||||
- 원인 추정:
|
||||
- `login_verifier`는 1회성으로, 기존 흐름(redirect_to 또는 consent app)에 의해 이미 사용됨
|
||||
- `login_verifier`만으로는 client 맥락이 부족하여 invalid_client 발생 가능
|
||||
|
||||
### 6) 임시 consent app(127.0.0.1:3000) 없이 redirect_to 직접 호출
|
||||
- 실패: consent app 미기동으로 연결 불가
|
||||
- 원인: login/consent UI URL이 기본값(127.0.0.1:3000)이라 실제 서비스 필요
|
||||
|
||||
### 7) Python 컨테이너에서 임시 consent app + 클라이언트 플로우 실행
|
||||
- 방법: python:3.12-alpine 컨테이너에서
|
||||
- 127.0.0.1:3000에 최소 consent 앱 실행
|
||||
- `/oauth2/auth` 호출을 따라가며 login/consent 자동 수락
|
||||
- 결과:
|
||||
- 첫 시도에서 `state` 길이 부족으로 `invalid_state` 발생
|
||||
- 이후 `state/nonce` 길이 충분히 늘려 재시도 중
|
||||
|
||||
## 현재 결론
|
||||
- 실제 consent 앱이 없으면 Hydra는 consent_challenge를 만들 수 없고 흐름이 중단됨.
|
||||
- 임시 consent 앱을 컨테이너 내부에서 띄우는 방식이 가장 현실적이며, 이 흐름으로 계속 진행 중.
|
||||
|
||||
### 8) devfront/hydra-rp-dummy.py + docker mount 실행
|
||||
- 방식: `hydra-rp-dummy.py`를 컨테이너에 마운트하여 임시 consent app(127.0.0.1:3000)으로 로그인/동의 자동 수락
|
||||
- 결과: 최종 리다이렉트가 `request_forbidden` (CSRF 쿠키 없음) 에러로 종료됨
|
||||
- 하지만 Hydra Admin 조회 결과 consent 세션은 생성됨
|
||||
- `handled_at`: 2026-01-30T05:01:46.770699Z
|
||||
- subject: `22607c1b-bfbf-4a90-9505-36b348472e7a`
|
||||
- client_id: `52a597f0-5b06-4fcb-b804-93e88a56a75a`
|
||||
- grant_scope: `openid profile email`
|
||||
|
||||
### 상태
|
||||
- consent 세션 생성 완료(확인됨)
|
||||
- 최종 리다이렉트 단계에서 CSRF 오류는 남아 있으나, 목적(연동/동의 저장)은 달성됨
|
||||
35
docs/trouble-shooting/issue-146-remote-login.md
Normal file
35
docs/trouble-shooting/issue-146-remote-login.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# #146 원격 링크 로그인 세션/이력 불일치 대응
|
||||
|
||||
## 요약
|
||||
- Ory 링크 로그인은 실제로 `/api/v1/auth/login/code/verify` 또는 `/api/v1/auth/login/code/verify-short` 경로를 사용합니다.
|
||||
- 기존에는 `verifyOnly`가 `/api/v1/auth/magic-link/verify`에만 적용되어, 링크를 클릭한 기기에서 세션이 발급되는 문제가 있었습니다.
|
||||
- 인증수단 표기는 loginId 기반 추론에 의존해 SMS 요청이 Email로 표시되는 문제가 있었습니다.
|
||||
|
||||
## 원인
|
||||
- verify-only 적용 범위가 magic link에 한정되어 있었고, Ory 코드 기반 경로는 세션을 즉시 발급했습니다.
|
||||
- audit 로그의 인증수단 표기는 request_body/loginId 기반 추론만 사용했습니다.
|
||||
|
||||
## 변경 사항
|
||||
### 1) verify-only 범위 확장
|
||||
- `/api/v1/auth/login/code/verify`, `/api/v1/auth/login/code/verify-short`에 `verifyOnly` 지원 추가
|
||||
- verify-only일 때는 승인 상태만 저장하고 세션 발급은 Polling(Desktop)에서 수행
|
||||
|
||||
### 2) Polling 시 세션 발급 주체 정리
|
||||
- 승인 상태(`status=approved`)는 **요청한 기기(A)**에서만 세션 발급
|
||||
- Ory 코드 플로우는 Polling 시점에 `VerifyLoginCode`를 수행해 세션 생성
|
||||
|
||||
### 3) 인증수단 표기 개선
|
||||
- `pendingRef` 기준으로 `login_method`(sms/email), `login_flow`(code/link) 저장
|
||||
- audit 로그에 해당 메타를 기록하여 SMS/Email, 코드/링크 구분을 명확히 표시
|
||||
- verify-only 요청 로그는 타임라인에서 제외
|
||||
|
||||
## 영향 범위
|
||||
- Backend: 링크 로그인 승인/세션 발급 경로 변경
|
||||
- Front: verify-only 플래그 전달 확장
|
||||
- 문서: auth-flow/test-plan 업데이트
|
||||
|
||||
## 테스트 계획 (요약)
|
||||
- Desktop에서 링크 요청 → Mobile에서 링크 클릭(verifyOnly) → Desktop Polling으로 세션 발급
|
||||
- Mobile 단말에서 세션/로그인 이력 미생성 확인
|
||||
- 인증수단 표기(SMS/Email) 정확성 확인
|
||||
- 코드/링크 만료/재사용 시나리오 점검
|
||||
Reference in New Issue
Block a user