OAuth 2.0 및 OpenID Connect 엔드포인트
상태:
planned. 이 페이지는 계획서(§13)에 명시된 모든 KeenAuth 환경의 프로토콜 표면을 설명합니다. 엔드포인트는 2단계에서 구현 중이며 아직 호스팅 환경에서 사용할 수 없습니다. 일반 제공 전까지 세부 사항은 변경될 수 있습니다.
모든 환경은 고유한 OAuth 2.0 인가 서버이자 OpenID Connect 공급자입니다. 엔드포인트는 관리 API의 일부가 아니며, 환경 호스트인 https://<environment-slug>.<region>.keenauth.app 또는 검증된 사용자 지정 도메인에 있습니다. 표에서 <issuer>는 환경의 issuer이며, 디스커버리 문서의 issuer 값입니다.
엔드포인트
| 엔드포인트 | 메서드 및 경로 | 클라이언트 인증 |
|---|---|---|
| 디스커버리 | GET <issuer>/.well-known/openid-configuration 및 GET <issuer>/.well-known/oauth-authorization-server (RFC 8414, 내용 동일) |
없음 |
| 키 | GET <issuer>/.well-known/jwks.json |
없음 |
| 인가 | GET 또는 POST <login host>/oauth2/authorize |
없음 (브라우저) |
| 푸시된 인가 요청 (RFC 9126) | POST <issuer>/oauth2/par |
기밀 클라이언트는 필수, 공개 클라이언트는 client_id 필요 |
| 토큰 | POST <issuer>/oauth2/token |
기밀 클라이언트는 필수, 공개 클라이언트는 client_id 필요 (DPoP는 선택 사항) |
| 기기 인가 (RFC 8628) | POST <issuer>/oauth2/device_authorization |
토큰 엔드포인트와 동일 |
| 해지 (RFC 7009) | POST <issuer>/oauth2/revoke |
토큰 엔드포인트와 동일 |
| 내성 (RFC 7662) | POST <issuer>/oauth2/introspect |
기밀 클라이언트만 가능 |
| UserInfo | GET 또는 POST <issuer>/oauth2/userinfo |
Bearer 또는 DPoP 액세스 토큰 |
| 세션 종료 | GET 또는 POST <login host>/oauth2/logout |
없음 (id_token_hint 또는 client_id) |
<login host>는 환경의 모든 로그인 도메인을 뜻하며, 기본 호스트 또는 추가된 사용자 지정 도메인이 해당합니다. 디스커버리 문서는 issuer 호스트에서만 제공됩니다. 다른 로그인 호스트에서 /.well-known/openid-configuration을 요청하면 본문에 issuer URL을 담은 404가 반환됩니다.
그랜트 유형
| 그랜트 | 용도 |
|---|---|
authorization_code |
브라우저 및 네이티브 로그인. PKCE S256이 필수입니다. |
refresh_token |
토큰을 갱신합니다. 사용할 때마다 리프레시 토큰이 교체되며, 이전 토큰을 재사용하면 토큰 패밀리 전체가 해지됩니다. |
client_credentials |
기기 간(machine-to-machine) 액세스. |
urn:ietf:params:oauth:grant-type:device_code |
TV나 명령줄 도구처럼 키보드가 없는 기기. |
urn:ietf:params:oauth:grant-type:token-exchange |
서비스 간 위임 및 가장(impersonation). |
암묵적 흐름(response_type=token 및 id_token을 포함하는 모든 값), 리소스 소유자 비밀번호 자격 증명 그랜트, 하이브리드 응답 유형은 현재와 향후 모두 지원되지 않습니다. RFC 9700은 앞의 두 가지를 금지합니다.
기기 인가
브라우저가 없는 기기는 POST <issuer>/oauth2/device_authorization을 호출해 흐름을 시작합니다. 기기 그랜트를 명시적으로 등록한 device 또는 native 유형의 애플리케이션만 이 흐름을 사용할 수 있습니다. 응답에는 device_code, user_code, 인증 주소가 포함됩니다. 사용자는 다른 기기에서 해당 주소를 열고 로그인한 뒤 승인합니다. 그동안 기기는 grant_type=urn:ietf:params:oauth:grant-type:device_code를 사용해 토큰 엔드포인트를 폴링합니다. user_code는 8자리이며 XXXX-XXXX 형식으로 표시됩니다. 기기 코드는 10분 동안 유효하며 한 번만 사용할 수 있습니다. 기기는 최대 5초마다 폴링해야 하며, 더 빠르게 폴링하면 slow_down이 반환되고 간격에 5초가 추가됩니다. verification_uri는 https://<login host>/u/device이며, 사용자는 승인하기 전에 애플리케이션, 요청된 스코프, 요청을 시작한 기기의 국가를 확인합니다.
보안 규칙
환경은 예외 없이 OAuth 2.0 보안 모범 사례(RFC 9700)를 따릅니다.
- 리디렉션 URI는 등록된 URI와 바이트 단위로 정확히 일치해야 합니다. 와일드카드는 사용할 수 없습니다.
- PKCE는
S256만 허용하며plain은 항상 거부됩니다. PKCE는 공개 클라이언트에 필수이며 모든 애플리케이션에서 기본으로 켜져 있습니다. 기밀web애플리케이션은 설정에서 이를 끌 수 있지만, 이 경우 환경이 여전히nonce를 요구해야 합니다. - 공식 SDK는 128비트
state와nonce를 보내고, 반환 시 두 값을 모두 검사합니다. - 인가 코드는 60초 동안 유효하며 한 번만 사용할 수 있습니다. 이미 사용된 코드를 제시하면
invalid_grant가 반환되고, 첫 번째 사용으로 발급된 리프레시 토큰과 액세스 토큰이 해지됩니다. - 푸시된 인가 요청을 사용하면 요청 파라미터가 브라우저 주소 표시줄에 노출되지 않습니다. 모든 요금제에서 사용할 수 있으며,
require_par설정을 켜면 애플리케이션 또는 환경 전체에 이를 필수로 적용할 수 있습니다. - 리프레시 토큰은 사용할 때마다 교체되며, 재사용 감지 시 해당 패밀리가 해지됩니다.
- DPoP(RFC 9449)는 액세스 토큰을 클라이언트가 보관하는 키에 바인딩합니다. API에서 바인딩된 토큰을 검증하는 방법은 API에서 토큰 검증하기를 참고하십시오.
세션과 로그아웃
로그인에 성공하면 환경은 로그인 호스트의 HttpOnly 쿠키에 단일 Single Sign-On 세션 하나를 보관합니다. 같은 환경의 애플리케이션은 이 세션을 재사용하므로, 정책상 더 강력하거나 최신인 인증이 필요하지 않다면 두 번째 애플리케이션에서 비밀번호를 다시 묻지 않습니다. 코드는 쿠키를 직접 보지 않으며, 인가 응답만 받습니다.
세션 종료 엔드포인트(OpenID Connect RP-Initiated Logout 1.0)는 해당 세션을 종료하고, 세션에 속한 리프레시 토큰을 해지하며, 백채널 로그아웃 주소를 등록한 애플리케이션에 알립니다. 백엔드에서 사용자의 세션을 조회하거나 해지하려면 관리 API의 세션 엔드포인트를 사용하십시오.
사용자가 엔터프라이즈 연결로 로그인했다면, 세션 종료 요청에 federated=true를 추가하여 ID 공급자에서도 로그아웃시킬 수 있습니다. 이 경우 먼저 여기의 세션이 종료되고, 브라우저는 ID 공급자의 로그아웃(SAML 단일 로그아웃 또는 OpenID 공급자의 세션 종료 엔드포인트)으로 이동한 뒤 post_logout_redirect_uri로 돌아옵니다. 이는 연결에서 ID 공급자 로그아웃이 켜져 있고 공급자가 로그아웃 주소를 공개한 경우에만 수행됩니다. 그렇지 않거나 공급자에 연결할 수 없으면, 이 파라미터가 없을 때와 같이 요청이 처리됩니다. ID 공급자에서 로그아웃하면 해당 공급자를 사용하는 사용자의 다른 애플리케이션도 종료될 수 있습니다.