1
0
forked from baron/baron-sso

ory스택 버전업 및 하드코딩URL 제거

This commit is contained in:
2026-05-07 10:27:31 +09:00
parent 13dee9ae9b
commit 45a14163bf
25 changed files with 1583 additions and 779 deletions

View File

@@ -23,7 +23,7 @@ sequenceDiagram
UF->>HY: 로그인 승인 요청
HY->>User: 권한 동의(Consent) 화면 표시
User->>HY: '허용' 클릭
HY-->>DF: 인증 코드와 함께 리다이렉트 (/callback?code=...)
HY-->>DF: 인증 코드와 함께 리다이렉트 (/auth/callback?code=...)
DF->>HY: 토큰 교환 요청 (Code -> ID/Access Token)
HY-->>DF: 토큰 발급
Note over DF: [FIX] 백엔드 /api/me 호출 대신<br/>ID Token에서 프로필 정보 직접 추출
@@ -46,7 +46,7 @@ sequenceDiagram
* 사용자가 '허용'을 누르면 Hydra는 `devfront`가 신뢰할 수 있는 앱임을 기록합니다.
4. **인증 코드 전달 및 토큰 교환 (Callback)**:
* Hydra는 사용자를 `devfront`의 콜백 페이지(`http://localhost:5174/callback?code=...`)로 보냅니다.
* Hydra는 사용자를 `devfront`의 콜백 페이지(`http://localhost:5174/auth/callback?code=...`)로 보냅니다.
* `devfront`는 이 코드를 Hydra의 토큰 엔드포인트로 보내 **ID Token**과 **Access Token**을 발급받습니다.
5. **사용자 정보 로드 (Profile Recovery)**:
@@ -71,9 +71,9 @@ hydra clients create
--response-types code
--scope openid,offline_access,profile,email
--token-endpoint-auth-method none \ # Public Client (PKCE 사용)
--callbacks http://localhost:5174/callback;
--callbacks http://localhost:5174/auth/callback;
```
이 설정으로 인해 `devfront`라는 ID의 클라이언트가 미리 존재하게 되며, `localhost:5174`로의 리다이렉션이 안전하게 허용됩니다.
이 설정으로 인해 `devfront`라는 ID의 클라이언트가 미리 존재하게 되며, `localhost:5174/auth/callback`로의 리다이렉션이 안전하게 허용됩니다.
---

View File

@@ -7,7 +7,8 @@
## 적용 범위
- UserFront, AdminFront, DevFront의 로그인/콜백 경로
- Ory Stack(Hydra/Kratos/Oathkeeper) 설정
- `compose.ory.yaml`, `gateway/nginx.conf`, `docker/ory/oathkeeper/rules*.json`
- `compose.ory.yaml`, `docker/compose.ory.yaml`, `docker/staging_pull_compose.template.yaml`
- `gateway/nginx.conf`, `deploy/templates/gateway/nginx.conf`, `docker/ory/oathkeeper/rules*.json`
- `Makefile` 기반 사전 검증/스모크 검증 단계
## 핵심 원칙
@@ -27,8 +28,8 @@
2. `mapped_match`
- Public URL과 Internal URL이 다르지만, 아래가 모두 성립
- Gateway 라우팅 규칙 존재 (예: `/oidc` rewrite)
- Oathkeeper `match``upstream` 규칙 존재 (예: `strip_path_prefix=/oidc`)
- Gateway 라우팅 규칙 존재: `/oidc` prefix를 제거하지 않고 Oathkeeper로 전달
- Oathkeeper `match``upstream` 규칙 존재: `/oidc/*` rule이 `strip_path=/oidc`로 Hydra에 전달
- 최종 업스트림이 기대 서비스(Hydra/Kratos)로 연결
3. `unmapped_fail`
@@ -42,6 +43,8 @@
- `ADMINFRONT_CALLBACK_URLS`, `DEVFRONT_CALLBACK_URLS` URL 유효성/중복/경로 규약
- Gateway `/oidc`, `/auth` 라우팅 규칙 존재 여부
- Oathkeeper `rules*.json`의 Hydra/Kratos 매핑 규칙 존재 여부
- staging pull/deploy template의 Oathkeeper entrypoint 사용 여부
- `KRATOS_ALLOWED_RETURN_URLS_JSON`에 공개 도메인, locale path, callback/return path가 포함되는지 여부
2. 런타임 검증 (`make verify-oidc-config`)
- OIDC Discovery endpoint 조회 가능 여부
@@ -49,9 +52,38 @@
- 필요 시 Gateway 경유 endpoint probe로 매핑 체인 확인
## 경로 규약
- DevFront callback: `/callback`
- DevFront callback: `/auth/callback`
- AdminFront callback: `/auth/callback`
- OrgFront callback: `/auth/callback`
- UserFront OIDC 진입점: `/oidc/*` (Gateway 경유)
- locale return path: `/ko`, `/en`, `/ko/auth/callback`, `/en/auth/callback`
## `/oidc` 책임 경계
- Gateway는 `/oidc` prefix를 보존합니다.
- Oathkeeper는 `/oidc/.well-known/*`, `/oidc/oauth2/*`, `/oidc/userinfo` rule에서 `strip_path=/oidc`를 적용합니다.
- Hydra는 prefix가 제거된 내부 경로(`/.well-known/*`, `/oauth2/*`, `/userinfo`)를 받습니다.
- 따라서 gateway template이나 staging pull compose에서 `rewrite ^/oidc`가 다시 들어가면 dev/stage/prod 간 책임 경계가 달라지므로 실패로 간주합니다.
## Oathkeeper rules 선택 정책
- Oathkeeper는 직접 `command: serve proxy ...`로 시작하지 않고 `/etc/config/oathkeeper/entrypoint.sh`를 통해 시작합니다.
- entrypoint는 `APP_ENV`에 따라 다음 파일을 선택하고 `/tmp/oathkeeper/rules.active.json`으로 복사합니다.
- `stage|staging`: `rules.stage.json`
- `production|prod`: `rules.prod.json`
- 그 외: `rules.json`
- `oathkeeper.yml``file:///tmp/oathkeeper/rules.active.json`만 읽습니다.
## Kratos allowed return URL 정책
- stage/prod에서는 `KRATOS_ALLOWED_RETURN_URLS_JSON`을 명시하는 것을 우선합니다.
- 최소 포함 대상:
- `KRATOS_UI_URL`, `KRATOS_UI_URL/`
- `USERFRONT_URL`, `USERFRONT_URL/`
- `USERFRONT_URL/ko`, `USERFRONT_URL/ko/`
- `USERFRONT_URL/en`, `USERFRONT_URL/en/`
- `USERFRONT_URL/auth/callback`
- `USERFRONT_URL/ko/auth/callback`
- `USERFRONT_URL/en/auth/callback`
- `ADMINFRONT_CALLBACK_URLS`, `DEVFRONT_CALLBACK_URLS`, `ORGFRONT_CALLBACK_URLS`
- private IP, legacy domain, comma-space가 포함된 URI 항목은 stage/prod 기본값으로 두지 않습니다.
## 운영 지침
1. 환경별 URL은 동일할 필요가 없고, 매핑 체인이 검증 가능해야 합니다.
@@ -65,3 +97,4 @@
- #272
- #274
- #276
- #710

View File

@@ -33,12 +33,14 @@ Ory 구성은 **컨테이너 내부 통신 URL**과 **브라우저 접근 URL**
### 내부 통신용 URL(컨테이너 네트워크)
- `KRATOS_PUBLIC_URL=http://kratos:4433`
- `KRATOS_ADMIN_URL=http://kratos:4434`
- `HYDRA_PUBLIC_URL=http://hydra:4444`
- `HYDRA_ADMIN_URL=http://hydra:4445`
- Hydra public upstream은 Oathkeeper rule 내부에서 `http://hydra:4444`로 전달합니다.
### 브라우저 접근용 URL(외부 도메인/프록시)
- `KRATOS_BROWSER_URL` : Kratos Public의 외부 URL
- `KRATOS_BROWSER_URL` : Kratos Public의 외부 URL. 보통 `${OATHKEEPER_PUBLIC_URL}/auth`
- `KRATOS_UI_URL` : UserFront의 외부 URL (Kratos UI 역할)
- `HYDRA_PUBLIC_URL` : Hydra issuer/OIDC discovery의 외부 URL. 보통 `${OATHKEEPER_PUBLIC_URL}/oidc`
- `VITE_OIDC_AUTHORITY` : 프론트엔드 OIDC authority. `HYDRA_PUBLIC_URL`과 같아야 합니다.
예시(로컬):
```env
@@ -48,8 +50,11 @@ KRATOS_UI_URL=http://localhost:5000
예시(리버스 프록시/도메인):
```env
KRATOS_BROWSER_URL=https://sso.example.com
OATHKEEPER_PUBLIC_URL=https://sso.example.com
KRATOS_BROWSER_URL=https://sso.example.com/auth
KRATOS_UI_URL=https://sso.example.com
HYDRA_PUBLIC_URL=https://sso.example.com/oidc
VITE_OIDC_AUTHORITY=https://sso.example.com/oidc
```
### 포트 노출 정책
@@ -64,6 +69,7 @@ Kratos는 self-service UI URL을 설정값으로 사용합니다. **UserFront의
- `KRATOS_SELFSERVICE_DEFAULT_BROWSER_RETURN_URL`
- `KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS`
- `KRATOS_SELFSERVICE_FLOWS_*_UI_URL`
- `KRATOS_ALLOWED_RETURN_URLS_JSON`
compose에서 기본적으로 다음과 같이 오버라이드합니다:
- `KRATOS_SELFSERVICE_FLOWS_LOGIN_UI_URL=${KRATOS_UI_URL}/login`
@@ -72,18 +78,44 @@ compose에서 기본적으로 다음과 같이 오버라이드합니다:
- `KRATOS_SELFSERVICE_FLOWS_RECOVERY_UI_URL=${KRATOS_UI_URL}/recovery`
- `KRATOS_SELFSERVICE_FLOWS_VERIFICATION_UI_URL=${KRATOS_UI_URL}/verification`
## 5) 트러블슈팅
### 5.1 로그인 클릭 시 동작 없음
stage/prod에서는 `KRATOS_ALLOWED_RETURN_URLS_JSON`에 공개 도메인과 callback/locale 경로를 명시합니다.
필수 후보:
- `${KRATOS_UI_URL}`, `${KRATOS_UI_URL}/`
- `${USERFRONT_URL}`, `${USERFRONT_URL}/`
- `${USERFRONT_URL}/ko`, `${USERFRONT_URL}/ko/`
- `${USERFRONT_URL}/en`, `${USERFRONT_URL}/en/`
- `${USERFRONT_URL}/auth/callback`
- `${USERFRONT_URL}/ko/auth/callback`
- `${USERFRONT_URL}/en/auth/callback`
- `${ADMINFRONT_CALLBACK_URLS}`, `${DEVFRONT_CALLBACK_URLS}`, `${ORGFRONT_CALLBACK_URLS}`
## 5) `/oidc` Gateway/Oathkeeper 책임 경계
Gateway는 `/oidc` prefix를 rewrite하지 않습니다. `/oidc/*` 요청은 prefix를 보존한 채 Oathkeeper로 전달하고, Oathkeeper rule이 `strip_path=/oidc`로 Hydra 내부 upstream(`http://hydra:4444`)에 전달합니다.
이 정책은 `gateway/nginx.conf`, `deploy/templates/gateway/nginx.conf`, `docker/ory/oathkeeper/rules*.json`, `docker/staging_pull_compose.template.yaml`에서 동일해야 합니다.
## 6) Oathkeeper active rules
Oathkeeper는 `/etc/config/oathkeeper/entrypoint.sh`를 통해 시작해야 합니다. entrypoint는 `APP_ENV`에 따라 env별 rules 파일을 고르고 `/tmp/oathkeeper/rules.active.json`을 생성합니다.
- `APP_ENV=stage|staging`: `rules.stage.json`
- `APP_ENV=production|prod`: `rules.prod.json`
- 그 외: `rules.json`
`docker/ory/oathkeeper/oathkeeper.yml``file:///tmp/oathkeeper/rules.active.json`을 읽습니다. compose나 배포 템플릿이 entrypoint를 우회해 `oathkeeper serve proxy`를 직접 실행하면 active rules 생성이 누락될 수 있습니다.
## 7) 트러블슈팅
### 7.1 로그인 클릭 시 동작 없음
- 원인: Kratos 기동 실패(설정 파싱 실패 등) 또는 브라우저용 URL이 내부 도메인(`kratos:...`)으로 설정됨
- 확인:
- `docker logs ory_kratos`에서 config 오류 여부 확인
- 브라우저 네트워크 탭에서 `/self-service/login/browser` 응답 확인(302 Location 헤더)
### 5.2 kratos.yml에 ${...} 환경 변수 치환 실패
### 7.2 kratos.yml에 ${...} 환경 변수 치환 실패
- Kratos 설정 파일은 `${ENV}` 치환을 지원하지 않음
- 해결: compose 환경 변수로 `KRATOS_SELFSERVICE_*`, `KRATOS_SERVE_*` 오버라이드 사용
## 6) 네트워크 접근 테스트
## 8) 네트워크 접근 테스트
아래 스크립트는 **ory-net에서 Admin 포트 접근 가능** / **baron_net(Frontend 영역)에서 접근 불가**를 검증합니다.
```bash
@@ -101,7 +133,7 @@ docker run --rm --network baron_net curlimages/curl:8.10.1 -fsS http://hydra:444
docker run --rm --network baron_net curlimages/curl:8.10.1 -fsS http://kratos:4434/health/ready
```
## 7) 참고 파일
## 9) 참고 파일
- `compose.ory.yaml`
- `docker/ory/kratos/kratos.yml`
- `.env.sample`