Files
keycloak-pattern/docs/ap4-edge-forward-auth.md
T

2.6 KiB

AP4 · oauth2-proxy Edge Forward Auth

첫 단계: oauth2-proxy 자체 OIDC 흐름

feature/keycloak-oauth2-proxy-oidc-flow에서는 oauth2-proxy를 http://localhost:4180에 직접 노출해 구성 요소를 분리해서 확인합니다.

  1. /edge/me 미인증 요청이 Keycloak로 redirect됩니다.
  2. oauth2-proxy는 confidential edge-proxy client와 PKCE S256을 사용합니다.
  3. callback에서 code/token 교환과 ID/access token 검증은 서버끼리 수행합니다.
  4. 브라우저에는 HttpOnly AP4_SESSION cookie만 남습니다.
  5. oauth2-proxy가 backend 요청에 X-Forwarded-User를 붙여 200을 받습니다.

Keycloak이 발급하는 issuer는 브라우저 기준 http://localhost:8080/realms/keycloak-patterns입니다. 컨테이너 내부의 localhost는 oauth2-proxy 자신이므로 discovery endpoint에 도달할 수 없습니다. 그래서 이 로컬 Compose 구성은 issuer 검증값은 외부 URL로 유지하되, login URL은 브라우저용 외부 주소, token/JWKS/userinfo는 http://keycloak:8080 내부 주소로 각각 명시합니다.

HTTP 로컬 시연이라 cookie-secure=false를 사용합니다. 운영 HTTPS에서는 반드시 secure cookie로 되돌려야 합니다.

다음 단계의 보안 전제

이 첫 feature의 backend는 전달된 사용자 헤더를 신뢰하며 8081도 loopback에 publish되어 있습니다. 따라서 로컬에서 직접 X-Forwarded-User: spoofed-admin을 보내면 우회가 재현됩니다. 이후 Nginx auth_request 통합을 거쳐 최종 feature에서 backend no-publish와 내부 shared-secret 검증을 함께 적용합니다.

두 번째 단계: Nginx auth_request

feature/keycloak-nginx-auth-request-integration부터 외부 진입점은 http://localhost:8088 Nginx 하나입니다. oauth2-proxy의 4180 포트는 Compose 네트워크에만 expose됩니다.

  • Nginx의 정확 일치 location = /oauth2/authinternal이라 외부에서 직접 호출할 수 없습니다.
  • 인증 서브리퀘스트에는 본문을 보내지 않고 Content-Length도 비웁니다.
  • 일반 브라우저 요청의 401은 /oauth2/start 302로 변환합니다.
  • API 요청 /api/edge는 redirect하지 않고 JSON 401을 반환합니다.
  • 인증 성공 시 oauth2-proxy의 X-Auth-Request-User와 email만 backend로 전달합니다.

Nginx 컨테이너 IP를 전용 Compose subnet에서 고정하고 oauth2-proxy의 trusted proxy를 그 단일 IP로 제한합니다. 다만 이 단계에서는 backend 8081이 로컬 호스트에 열려 있어 신뢰 헤더를 직접 위조할 수 있습니다. 그 재현 조건은 마지막 feature에서 제거합니다.