RFC 9449 OAuth DPoP 2023년 9월
Fett, et al. 표준 트랙 [페이지]
스트림:
인터넷 엔지니어링 태스크 포스(IETF)
RFC:
9449
분류:
표준 트랙
발행일:
ISSN:
2070-1721
저자:
D. Fett
Authlete
B. Campbell
Ping Identity
J. Bradley
Yubico
T. Lodderstedt
Tuconic
M. Jones
Self-Issued Consulting
D. Waite
Ping Identity

RFC 9449

OAuth 2.0 소유 증명 입증(DPoP)

초록

이 문서는 애플리케이션 수준의 소유 증명 메커니즘을 통해 OAuth 2.0 토큰에 발신자 제한을 적용하는 메커니즘을 설명한다. 이 메커니즘은 액세스 토큰 및 리프레시 토큰을 이용한 재전송 공격을 탐지할 수 있게 한다.

이 메모의 상태

이것은 인터넷 표준 트랙 문서이다.

이 문서는 인터넷 엔지니어링 태스크 포스(IETF)의 산물이다. 이는 IETF 커뮤니티의 합의를 나타낸다. 공개 검토를 받았으며 인터넷 엔지니어링 운영 그룹(IESG)의 발행 승인을 받았다. 인터넷 표준에 대한 추가 정보는 RFC 7841의 섹션 2에서 확인할 수 있다.

이 문서의 현재 상태, 정오표, 그리고 이에 대한 피드백 제공 방법에 관한 정보는 https://www.rfc-editor.org/info/rfc9449에서 확인할 수 있다.

목차

1. 소개

Demonstrating Proof of Possession(DPoP)는 OAuth [RFC6749] 액세스 토큰 및 리프레시 토큰에 발신자 제한을 적용하기 위한 애플리케이션 수준 메커니즘이다. 이는 클라이언트가 HTTP 요청에 DPoP 헤더를 포함함으로써 공개/개인 키 쌍의 소유를 증명할 수 있게 한다. 이 헤더의 값은 JSON Web Token (JWT) [RFC7519]이며, 이를 통해 인가 서버는 발급된 토큰을 클라이언트 키 쌍의 공개 부분에 바인딩할 수 있다. 그런 토큰의 수신자는 이후 클라이언트가 DPoP 헤더를 통해 자신이 보유함을 입증한 키 쌍에 토큰이 바인딩되어 있는지 검증할 수 있으며, 이로써 토큰을 제시하는 클라이언트가 개인 키도 소유하고 있다는 어느 정도의 보증을 제공한다. 달리 말하면, 토큰의 정당한 제시자는 키 쌍의 개인 부분을 보유하고 그 소유를 증명하는 발신자로 제한된다.

여기서 명시하는 메커니즘은 [RFC8705] 또는 [TOKEN-BINDING]처럼 기반 보안 전송 계층의 요소를 활용하는 다른 토큰 발신자 제한 방식이 사용할 수 없거나 바람직하지 않은 경우에 사용할 수 있다. 예를 들어, 사용자 에이전트에서 TLS 클라이언트 인증의 사용자 경험이 좋지 않고 HTTP 토큰 바인딩 지원이 부족하기 때문에, OAuth 클라이언트가 웹 브라우저에서 동적으로 다운로드되어 실행되는 애플리케이션(때로는 "single-page application"이라고 함)인 경우에는 어느 메커니즘도 사용할 수 없다. 또한 사용자의 장치에 직접 설치되어 실행되는 애플리케이션은 손상되었거나 악의적인 리소스에 의한 토큰 오용을 방지하는 DPoP 바인딩 토큰의 이점을 얻기에 적합하다. 이러한 애플리케이션에는 암호화 키를 위한 전용 보호 저장소가 있는 경우가 많다.

DPoP는 사용되는 클라이언트 인증 방법과 관계없이 액세스 토큰에 발신자 제한을 적용하는 데 사용할 수 있지만, DPoP 자체는 클라이언트 인증에 사용되지 않는다. DPoP는 공개 클라이언트(client_id와 연결된 인증 자격 증명이 없는 클라이언트)에 발급된 리프레시 토큰에 발신자 제한을 적용하는 데도 사용할 수 있다.

1.1. 규약 및 용어

이 문서의 핵심 단어 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", 및 "OPTIONAL"은 여기에 표시된 것처럼 모두 대문자로 나타날 때에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석한다.

이 명세는 [RFC5234]의 Augmented Backus-Naur Form(ABNF) 표기법을 사용한다.

이 명세는 "The OAuth 2.0 Authorization Framework" [RFC6749]에서 정의한 "access token", "refresh token", "authorization server", "resource server", "authorization endpoint", "authorization request", "authorization response", "token endpoint", "grant type", "access token request", "access token response", "client", "public client", 및 "confidential client"라는 용어를 사용한다.

"request", "response", "header field", 및 "target URI"라는 용어는 [RFC9110]에서 가져온다.

"JOSE" 및 "JOSE Header"라는 용어는 [RFC7515]에서 가져온다.

이 문서에는 부분 및 완전한 HTTP 메시지의 비규범적 예제가 포함되어 있다. 일부 예제는 긴 값을 줄바꿈했음을 나타내기 위해 [RFC8792]에 따라 하나의 후행 백슬래시를 사용한다. 줄바꿈된 행의 문자와 선행 공백은 값의 일부가 아니다.

2. 목표

DPoP의 주요 목적은 토큰을 발급할 때 공개 키에 바인딩하고 토큰을 사용할 때 클라이언트가 대응하는 개인 키의 소유를 증명하도록 요구함으로써, 허가되지 않았거나 정당하지 않은 당사자가 유출되거나 도난당한 액세스 토큰을 사용하는 것을 방지하는 것이다. 이는 토큰의 정당한 발신자를 개인 키에 접근할 수 있는 당사자로만 제한하며, 토큰을 수신하는 서버에 발신자가 그 토큰을 사용할 정당한 권한을 가지고 있다는 추가 보증을 제공한다.

따라서 DPoP를 통해 발신자 제한이 적용된 액세스 토큰은 그러한 토큰을 소유한 모든 당사자가 사용할 수 있는 일반적인 베어러 토큰과 대비된다. 베어러 토큰의 의도치 않은 노출을 방지하기 위한 보호 조치는 일반적으로 존재하지만, 프로토콜 또는 소프트웨어 스택의 다른 계층에 있는 취약점과 구현 문제로 인해 예기치 못한 유출 벡터가 발생한 적이 있다(예: Compression Ratio Info-leak Made Easy(CRIME) [CRIME], Browser Reconnaissance and Exfiltration via Adaptive Compression of Hypertext(BREACH) [BREACH], Heartbleed [Heartbleed], 및 Cloudflare parser bug [Cloudbleed]). OAuth 구현 자체에 대한 수많은 공개된 토큰 탈취 공격도 있었다 ([GitHub.Tokens]는 그중 하나의 유명한 사례일 뿐이다). DPoP는 예기치 못한 토큰 유출의 영향에 대해 일반적인 심층 방어를 제공한다. 그러나 DPoP는 보안 전송을 대체하는 것이 아니며, 항상 HTTPS와 함께 사용되어야 MUST 한다.

일반적인 OAuth 프로토콜 상호작용의 특성상 클라이언트는 접근하는 보호된 리소스에 액세스 토큰을 공개해야 한다. [SECURITY-TOPICS]의 공격자 모델은 보호된 리소스가 위조되었거나 악의적이거나 손상되어, 수신한 토큰을 다른 보호된 리소스에 재사용함으로써 무단 접근을 얻는 경우를 설명한다. 대상 제한 액세스 토큰 (예: JWT [RFC7519] aud 클레임 사용)은 이러한 오용을 방지할 수 있다. 그러나 실제로는 그런 방식이 많은 배포에서 지나치게 번거로운 것으로 드러났다([RFC8707] 같은 확장이 있음에도 불구하고). 액세스 토큰에 발신자 제한을 적용하는 것은 다른 엔드포인트에서의 그러한 토큰 재전송을 방지하기 위한 더 견고하고 간단한 메커니즘이며, DPoP는 이를 수행하는 접근 가능한 애플리케이션 계층 수단이다.

크로스 사이트 스크립팅(XSS)의 가능성 때문에, 브라우저 기반 OAuth 클라이언트는 토큰 보호와 관련해 추가적인 고려사항을 가져온다. 가장 직접적인 XSS 기반 공격은 공격자가 토큰을 유출하여 정당한 클라이언트와 완전히 독립적으로 직접 사용하는 것이다. 도난당한 액세스 토큰은 보호된 리소스 접근에 사용되고, 도난당한 리프레시 토큰은 새 액세스 토큰을 얻는 데 사용된다. 개인 키가 추출 불가능한 경우([W3C.WebCryptoAPI]로 가능한 것처럼), DPoP는 유출된 토큰만으로는 사용할 수 없게 만든다.

XSS 취약점은 또한 공격자가 브라우저 기반 클라이언트 애플리케이션의 컨텍스트에서 코드를 실행하고, 클라이언트를 통해 간접적으로 토큰을 악의적으로 사용하도록 허용한다. 그 실행 컨텍스트는 서명 키를 활용할 수 있는 접근 권한을 가지므로, 토큰과 함께 사용할 DPoP 증명을 생성할 수 있다. 이 애플리케이션 계층에서는 일반적으로 XSS를 방지하는 것 외에는 이 위협에 대한 실현 가능한 방어가 없을 가능성이 높으므로, 이는 DPoP의 범위 밖으로 간주된다.

브라우저 기반 클라이언트 애플리케이션의 컨텍스트에서 실행되는 악의적인 XSS 코드는 미래의 타임스탬프 값을 가진 DPoP 증명을 만들고, 이를 토큰과 함께 유출할 수 있는 위치에도 있다. 이러한 도난당한 산출물은 나중에 클라이언트 애플리케이션과 독립적으로 보호된 리소스에 접근하는 데 사용될 수 있다. 이를 방지하기 위해 서버는 클라이언트가 공격자가 예측할 수 없는 서버 선택 값을 증명에 포함하도록 선택적으로 요구할 수 있다(nonce). 선택적 nonce가 없는 경우, 사전 계산된 DPoP 증명의 영향은 보호된 리소스 접근에서 증명이 액세스 토큰에 바인딩되어 있다는 점에 의해 어느 정도 제한된다. 아직 존재하지 않는 액세스 토큰을 포괄하는 증명은 실현 가능하게 만들 수 없기 때문에, 유출된 리프레시 토큰과 사전 계산된 증명으로 얻은 액세스 토큰은 사용할 수 없다.

추가 보안 고려사항은 섹션 11에서 논의한다.

3. 개념

이 명세가 도입하는 주요 데이터 구조는 아래에서 자세히 설명하는 것처럼 HTTP 요청의 헤더로 전송되는 DPoP 증명 JWT이다. 클라이언트는 DPoP 증명 JWT를 사용하여 특정 공개 키에 대응하는 개인 키의 소유를 증명한다.

대략적으로 말해, DPoP 증명은 다음 항목들에 대한 서명이다.

+--------+                                          +---------------+
|        |--(A)-- Token Request ------------------->|               |
| Client |        (DPoP Proof)                      | Authorization |
|        |                                          |     Server    |
|        |<-(B)-- DPoP-Bound Access Token ----------|               |
|        |        (token_type=DPoP)                 +---------------+
|        |
|        |
|        |                                          +---------------+
|        |--(C)-- DPoP-Bound Access Token --------->|               |
|        |        (DPoP Proof)                      |    Resource   |
|        |                                          |     Server    |
|        |<-(D)-- Protected Resource ---------------|               |
|        |                                          +---------------+
+--------+
그림 1: 기본 DPoP 흐름

DPoP를 사용하는 OAuth 흐름의 기본 단계(선택적 nonce 없음)는 그림 1에 나와 있다.

  1. 토큰 요청에서 클라이언트는 액세스 토큰 (및 잠재적으로 리프레시 토큰)을 얻기 위해 인가 그랜트 (예: 인가 코드, 리프레시 토큰 등)를 인가 서버에 보낸다. 클라이언트는 HTTP 헤더에 DPoP 증명을 첨부한다.
  2. 인가 서버는 액세스 토큰을 DPoP 증명에서 클라이언트가 주장한 공개 키에 바인딩한다(발신자 제한을 적용한다). 즉, 해당 개인 키의 소유를 증명하지 않고는 액세스 토큰을 사용할 수 없다. 공개 클라이언트에 리프레시 토큰이 발급되는 경우, 그 토큰도 DPoP 증명의 공개 키에 바인딩된다.
  3. 액세스 토큰을 사용하려면, 클라이언트는 다시 해당 요청에 대한 DPoP 증명을 담은 헤더를 요청에 추가하여 개인 키의 소유를 증명해야 한다. 리소스 서버는 액세스 토큰이 바인딩된 공개 키에 대한 정보를 받아야 한다. 이 정보는 (JWT 구조의 액세스 토큰의 경우) 액세스 토큰에 직접 인코딩될 수 있거나 토큰 인트로스펙션 엔드포인트를 통해 제공될 수 있다(그림에는 표시되지 않음). 리소스 서버는 액세스 토큰이 바인딩된 공개 키가 DPoP 증명의 공개 키와 일치하는지 검증한다. 또한 DPoP 증명의 액세스 토큰 해시가 요청에 제시된 액세스 토큰과 일치하는지 검증한다.
  4. 서명 검사가 실패하거나 DPoP 증명의 데이터가 잘못된 경우, 예를 들어 대상 URI가 DPoP 증명 JWT의 URI 클레임과 일치하지 않는 경우, 리소스 서버는 요청 처리를 거부한다. 물론 액세스 토큰 자체도 다른 모든 측면에서 유효해야 한다.

여기서 제시하는 DPoP 메커니즘은 클라이언트 인증 방법이 아니다. 실제로 DPoP의 주요 사용 사례는 클라이언트 인증을 사용하지 않는 공개 클라이언트(예: 단일 페이지 애플리케이션 및 사용자 장치의 애플리케이션)를 위한 것이다. 그럼에도 불구하고 DPoP는 private_key_jwt 및 모든 다른 클라이언트 인증 방법과 호환되도록 설계되었다.

DPoP는 메시지 무결성을 직접 보장하지 않으며, 그 목적을 위해 TLS 계층에 의존한다. 자세한 내용은 섹션 11을 참조한다.

4. DPoP 증명 JWT

DPoP는 클라이언트가 생성하고 DPoP 헤더 필드를 사용해 HTTP 요청과 함께 보내는 JWT인 DPoP 증명이라는 개념을 도입한다. 각 HTTP 요청에는 고유한 DPoP 증명이 필요하다.

유효한 DPoP 증명은 클라이언트가 DPoP 증명 JWT를 서명하는 데 사용된 개인 키를 보유하고 있음을 서버에 입증한다. 이를 통해 인가 서버는 ( 섹션 5에 설명된 대로) 발급된 토큰을 대응하는 공개 키에 바인딩할 수 있으며, 리소스 서버는 수신한 토큰의 키 바인딩을 검증할 수 있다 (섹션 7.1 참조). 이는 해당 개인 키에 접근할 수 없는 어떤 엔터티도 그 토큰을 사용할 수 없도록 방지한다.

DPoP 증명은 키의 소유를 입증하지만, 그 자체로는 인증 또는 접근 제어 메커니즘이 아니다. 섹션 7.1에 설명된 것처럼 키 바인딩 액세스 토큰과 함께 제시될 때, DPoP 증명은 액세스 토큰을 제시하는 클라이언트의 정당성에 대한 추가 보증을 제공한다. 그러나 유효한 DPoP 증명 JWT만으로는 접근 제어 결정을 내리기에 충분하지 않다.

4.1. DPoP HTTP 헤더

DPoP 증명은 다음 요청 헤더 필드를 사용하여 HTTP 요청에 포함된다.

DPoP:
섹션 4.2의 구조와 구문을 따르는 JWT.

그림 2는 DPoP HTTP 헤더 필드 예제를 보여준다. 이 예제는 [RFC8792]에 따른 "\" 줄바꿈을 사용한다.

DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg
그림 2: DPoP 헤더 예제

[RFC9110]에 따르면 헤더 필드 이름은 대소문자를 구분하지 않는다. 따라서 DPoP, DPOP, dpop 등은 모두 유효하고 동등한 헤더 필드 이름이다. 그러나 헤더 필드 값에서는 대소문자가 중요하다.

DPoP HTTP 헤더 필드 값은 섹션 11.2 of [RFC9110]에 정의된 token68 구문을 사용하며, 참조의 편의를 위해 아래 그림 3에 다시 제시한다.

DPoP       = token68
token68    = 1*( ALPHA / DIGIT /
                 "-" / "." / "_" / "~" / "+" / "/" ) *"="
그림 3: DPoP 헤더 필드 ABNF

4.2. DPoP 증명 JWT 구문

DPoP 증명은 클라이언트가 선택한 개인 키(아래 참조)로 서명된(JSON Web Signature(JWS) [RFC7515] 사용) JWT [RFC7519]이다. DPoP JWT의 JOSE Header는 최소한 다음 매개변수를 포함해야 MUST 한다.

typ:
섹션 3.11 of [RFC8725]에서 권장하는 것처럼 DPoP 증명 JWT를 명시적으로 형식화하는 dpop+jwt 값을 가진 필드.
alg:
[IANA.JOSE.ALGS]의 JWS 비대칭 디지털 서명 알고리즘에 대한 식별자. 이는 none 또는 대칭 알고리즘(Message Authentication Code(MAC))의 식별자여서는 안 된다 MUST NOT.
jwk:
섹션 4.1.3 of [RFC7515]에 정의된 것처럼 JSON Web Key(JWK) [RFC7517] 형식으로 클라이언트가 선택한 공개 키를 나타낸다. 이는 개인 키를 포함해서는 안 된다 MUST NOT.

DPoP 증명의 페이로드는 최소한 다음 클레임을 포함해야 MUST 한다.

jti:
DPoP 증명 JWT의 고유 식별자. 이 값은 유효 기간 동안 동일한 컨텍스트에서 사용되는 다른 DPoP 증명에 같은 값이 할당될 확률이 무시할 수 있을 정도가 되도록 할당되어야 MUST 한다. 이러한 고유성은 최소 96비트의 의사난수 데이터를 인코딩(base64url 또는 그 밖의 적절한 인코딩)하거나, [RFC4122]에 따른 버전 4 Universally Unique Identifier(UUID) 문자열을 사용하여 달성할 수 있다. jti는 서버가 재전송 탐지 및 방지를 위해 사용할 수 있다. 섹션 11.1을 참조한다.
htm:
JWT가 첨부된 요청의 HTTP 메서드(섹션 9.1 of [RFC9110]) 값.
htu:
JWT가 첨부된 요청의 HTTP 대상 URI(섹션 7.1 of [RFC9110])로, 쿼리와 프래그먼트 부분은 제외한다.
iat:
JWT의 생성 타임스탬프 (섹션 4.1.6 of [RFC7519]).

DPoP 증명이 보호된 리소스 접근에서 액세스 토큰의 제시와 함께 사용되는 경우( 섹션 7 참조), DPoP 증명은 다음 클레임도 포함해야 MUST 한다.

ath:
액세스 토큰의 해시. 이 값은 관련 액세스 토큰 값의 ASCII 인코딩에 대한 SHA-256 [SHS] 해시를 base64url 인코딩(섹션 2 of [RFC7515]에 정의됨)한 결과여야 MUST 한다.

인증 서버 또는 리소스 서버가 응답에 DPoP-Nonce HTTP 헤더를 제공하는 경우(섹션 89 참조), DPoP 증명은 다음 클레임도 포함해야 MUST 한다.

nonce:
DPoP-Nonce HTTP 헤더를 통해 제공된 최신 nonce.

DPoP 증명은 확장, 프로파일 또는 배포별 요구사항에 의해 정의된 다른 JOSE Header Parameters 또는 클레임을 포함할 수 있다 MAY.

그림 4그림 2의 DPoP 증명을 디코딩한 내용을 보여주는 개념적 예제이다. JWT 헤더와 페이로드의 JSON은 표시하지만, 서명 부분은 생략했다. 일반적으로 줄바꿈과 추가 공백은 형식 지정과 가독성을 위해 포함되어 있다.

{
  "typ":"dpop+jwt",
  "alg":"ES256",
  "jwk": {
    "kty":"EC",
    "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
    "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
    "crv":"P-256"
  }
}
.
{
  "jti":"-BwC3ESc6acc2lTc",
  "htm":"POST",
  "htu":"https://server.example.com/token",
  "iat":1562262616
}
그림 4: DPoP 증명의 JWT 내용 예제

HTTP 요청 중 HTTP 메서드와 URI만 DPoP JWT에 포함된다. 따라서 이 두 메시지 부분만 DPoP 증명에 의해 포괄된다. 이 아이디어는 HTTP 요청과 관련된 합리적인 소유 증명을 제공하기에 충분한 HTTP 데이터만 서명하는 것이다. HTTP 헤더 데이터의 최소 하위 집합만 사용하는 이 설계 접근 방식은 HTTP 메시지를 정규화하려는 시도에 내재된 상당한 어려움을 피하기 위한 것이다. 그럼에도 불구하고 DPoP 증명은 HTTP 요청의 다른 정보를 포함하도록 확장될 수 있다(섹션 11.7도 참조).

4.3. DPoP 증명 검사

DPoP 증명을 검증하기 위해, 수신 서버는 다음을 보장해야 MUST 한다.

  1. DPoP HTTP 요청 헤더 필드가 하나를 초과하지 않는다.
  2. DPoP HTTP 요청 헤더 필드 값은 단일하고 잘 형성된 JWT이다.
  3. 섹션 4.2에 따른 모든 필수 클레임이 JWT에 포함되어 있다.
  4. typ JOSE Header Parameter는 dpop+jwt 값을 가진다.
  5. alg JOSE Header Parameter는 등록된 비대칭 디지털 서명 알고리즘 [IANA.JOSE.ALGS]을 나타내며, none이 아니고, 애플리케이션이 지원하며, 로컬 정책에 따라 허용 가능하다.
  6. JWT 서명은 jwk JOSE Header Parameter에 포함된 공개 키로 검증된다.
  7. jwk JOSE Header Parameter는 개인 키를 포함하지 않는다.
  8. htm 클레임은 현재 요청의 HTTP 메서드와 일치한다.
  9. htu 클레임은 JWT가 수신된 HTTP 요청의 HTTP URI 값과 일치하되, 쿼리 및 프래그먼트 부분은 무시한다.
  10. 서버가 클라이언트에 nonce 값을 제공한 경우, nonce 클레임은 서버 제공 nonce 값과 일치한다.
  11. JWT의 생성 시간은 iat 클레임 또는 nonce 클레임을 통한 서버 관리 타임스탬프 중 하나로 결정되며, 허용 가능한 시간 창 내에 있다(섹션 11.1 참조).
  12. 액세스 토큰과 함께 보호된 리소스에 제시된 경우,

    • ath 클레임의 값이 해당 액세스 토큰의 해시와 같은지 보장하고,
    • 액세스 토큰이 바인딩된 공개 키가 DPoP 증명의 공개 키와 일치하는지 확인한다.

거짓 부정의 가능성을 줄이기 위해, 서버는 htu 클레임을 비교하기 전에 구문 기반 정규화(섹션 6.2.2 of [RFC3986]) 및 스킴 기반 정규화(섹션 6.2.3 of [RFC3986])를 사용해야 SHOULD 한다.

이러한 검사는 어떤 순서로 수행해도 된다.

5. DPoP 액세스 토큰 요청

DPoP를 사용하여 공개 키에 바인딩된 액세스 토큰을 요청하려면, 클라이언트는 MUST 인가 서버의 토큰 엔드포인트에 액세스 토큰 요청을 할 때 DPoP 헤더에 유효한 DPoP 증명 JWT를 제공해야 한다. 이는 그랜트 유형과 관계없이 모든 액세스 토큰 요청에 적용된다(예: 일반적인 authorization_coderefresh_token 그랜트 유형과 JWT 인가 그랜트 [RFC7523]와 같은 확장 그랜트). 그림 5에 표시된 HTTP 요청은 DPoP 헤더의 DPoP 증명 JWT와 함께 인가 코드 그랜트를 사용하는 이러한 액세스 토큰 요청을 예시한다. 그림 5[RFC8792]에 따른 "\" 줄바꿈을 사용한다.

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg

grant_type=authorization_code\
&client_id=s6BhdRkqt\
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\
&code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz-
그림 5: 인가 코드를 사용한 DPoP 발신자 제한 토큰 요청

DPoP HTTP 헤더 필드는 유효한 DPoP 증명 JWT를 포함해야 MUST 한다. DPoP 증명이 유효하지 않으면, 인가 서버는 error 매개변수의 값으로 invalid_dpop_proof를 사용하여 섹션 5.2 of [RFC6749]에 따른 오류 응답을 발행한다.

DPoP 증명의 유효성을 확인한 후 액세스 토큰에 발신자 제한을 적용하기 위해, 인가 서버는 발급된 액세스 토큰을 DPoP 증명의 공개 키와 연결하며, 이는 섹션 6에 설명된 대로 수행할 수 있다. 액세스 토큰 응답에는 DPoPtoken_type이 포함되어야 MUST 하며, 이는 액세스 토큰이 클라이언트의 DPoP 키에 바인딩되었고 섹션 7.1에 설명된 대로 사용할 수 있음을 클라이언트에 알리기 위한 것이다. 그림 6에 표시된 예제 응답은 그러한 응답을 예시한다.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
 "access_token": "Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU",
 "token_type": "DPoP",
 "expires_in": 2677,
 "refresh_token": "Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g"
}
그림 6: 액세스 토큰 응답

그림 6의 예제 응답에는 이전 토큰이 만료될 때 클라이언트가 새 액세스 토큰을 얻는 데 사용할 수 있는 리프레시 토큰이 포함되어 있다. 액세스 토큰 갱신은 인가 서버의 토큰 엔드포인트에 대해 refresh_token 그랜트 유형을 사용하여 수행되는 토큰 요청이다. 모든 액세스 토큰 요청과 마찬가지로, 클라이언트는 그림 7에 표시된 것처럼 DPoP 증명을 포함하여 이를 DPoP 요청으로 만든다. 그림 7[RFC8792]에 따른 "\" 줄바꿈을 사용한다.

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjY1Mjk2fQ.pAqut2IRDm_De6PR93SYmGBPXpwrAk90e8cP2hjiaG5Qs\
 GSuKDYW7_X620BxqhvYC8ynrrvZLTk41mSRroapUA

grant_type=refresh_token\
&client_id=s6BhdRkqt\
&refresh_token=Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g
그림 7: 리프레시 토큰을 사용한 DPoP 바인딩 토큰 요청

DPoP를 지원하는 인가 서버가 토큰 엔드포인트에서 유효한 DPoP 증명을 제시하는 공개 클라이언트에 리프레시 토큰을 발급하는 경우, 리프레시 토큰은 해당 공개 키에 바인딩되어야 MUST 한다. 리프레시 토큰이 나중에 새 액세스 토큰을 얻기 위해 제시될 때 그 바인딩은 검증되어야 MUST 한다. 결과적으로, 그러한 클라이언트는 리프레시 토큰을 사용하여 새 액세스 토큰을 얻을 때마다 그 리프레시 토큰을 얻는 데 사용된 것과 동일한 키에 대한 DPoP 증명을 제시해야 MUST 한다. 리프레시 토큰 바인딩의 구현 세부사항은 인가 서버의 재량에 따른다. 인가 서버가 자신의 리프레시 토큰을 생성하고 검증하므로, 바인딩의 구체적인 세부사항에는 상호운용성 고려사항이 없다.

인가 서버는 DPoP 바인딩되지 않은 액세스 토큰을 발급하도록 선택할 수 있으며 MAY, 이는 [RFC6750]에 따라 액세스 토큰 응답의 token_type 매개변수에 Bearer 값을 사용하여 클라이언트에 신호된다. 리프레시 토큰도 발급받는 공개 클라이언트의 경우, 이는 리프레시 토큰만 DPoP 바인딩하는 효과가 있으며, 보호된 리소스가 DPoP를 지원하도록 업데이트되지 않은 경우에도 보안 태세를 개선할 수 있다.

액세스 토큰 응답에 DPoP와 다른 token_type 값이 포함되어 있으면, DPoP가 제공하는 액세스 토큰 보호는 제공되지 않는다. 이 보호가 애플리케이션의 보안에 중요하다고 간주되는 경우, 클라이언트는 이 응답을 폐기해야 MUST 한다. 그렇지 않으면 클라이언트는 일반 OAuth 상호작용처럼 계속할 수 있다.

기밀 클라이언트(인가 서버와 인증 자격 증명을 설정한 클라이언트)에 발급되는 리프레시 토큰은 이미 다른 기존 메커니즘으로 발신자 제한이 적용되어 있으므로 DPoP 증명 공개 키에 바인딩되지 않는다. OAuth 2.0 Authorization Framework [RFC6749]는 인가 서버가 리프레시 토큰을 그것이 발급된 클라이언트에 바인딩하고, 기밀 클라이언트가 리프레시 토큰을 제시할 때 인가 서버에 인증하도록 이미 요구한다. 결과적으로 이러한 리프레시 토큰은 클라이언트 식별자와 관련 인증 요구사항을 통해 발신자 제한이 적용된다. 이 기존 발신자 제한 메커니즘은 특정 공개 키에 직접 바인딩하는 것보다 더 유연하다 (예: 리프레시 토큰을 무효화하지 않고 클라이언트의 자격 증명 순환을 허용함).

5.1. 인가 서버 메타데이터

이 문서는 DPoP에 대한 일반적인 지원과 인가 서버가 DPoP 증명 JWT에 대해 지원하는 구체적인 JWS alg 값을 신호하기 위해 다음 인가 서버 메타데이터 [RFC8414] 매개변수를 도입한다.

dpop_signing_alg_values_supported:
인가 서버가 DPoP 증명 JWT에 대해 지원하는 JWS alg 값([IANA.JOSE.ALGS] 레지스트리의 값) 목록을 포함하는 JSON 배열.

5.2. 클라이언트 등록 메타데이터

Dynamic Client Registration Protocol [RFC7591]은 OAuth 2.0 클라이언트 메타데이터를 인가 서버에 동적으로 등록하기 위한 API를 정의한다. [RFC7591]에서 정의한 메타데이터와 이에 등록된 확장은 Dynamic Client Registration Protocol이 사용되지 않는 경우에도 인가 서버 구현에 유용한 클라이언트의 일반 데이터 모델을 함축한다. 그러한 구현에는 일반적으로 클라이언트 구성을 관리하기 위한 일종의 사용자 인터페이스가 제공된다.

이 문서는 클라이언트가 인가 서버에서 토큰을 요청할 때 항상 DPoP를 사용함을 나타내기 위해 다음 클라이언트 등록 메타데이터 [RFC7591] 매개변수를 도입한다.

dpop_bound_access_tokens:
클라이언트가 토큰 요청에 항상 DPoP를 사용하는지 여부를 지정하는 불리언 값. 생략된 경우 기본값은 false이다.

값이 true인 경우, 인가 서버는 DPoP 헤더를 포함하지 않는 해당 클라이언트의 토큰 요청을 거부해야 MUST 한다.

6. 공개 키 확인

리소스 서버는 액세스 토큰이 DPoP 바인딩되었는지 신뢰성 있게 식별하고, DPoP 증명의 공개 키에 대한 바인딩을 검증하기에 충분한 정보를 확인할 수 있어야 MUST 한다(섹션 7.1 참조). 이러한 바인딩은 보호된 리소스가 접근할 수 있는 방식으로 공개 키를 토큰과 연결함으로써 이루어진다. 예를 들어 발급된 액세스 토큰에 JWK 해시를 직접 임베딩하고 섹션 6.1에 설명된 구문을 사용하거나, 섹션 6.2에 설명된 대로 토큰 인트로스펙션을 통해 수행할 수 있다. 공개 키를 액세스 토큰과 연결하는 다른 방법도 인가 서버와 보호된 리소스 간의 합의에 따라 가능하다. 그러나 이는 이 명세의 범위를 벗어난다.

DPoP를 지원하는 리소스 서버는 DPoP 증명의 공개 키가 액세스 토큰에 바인딩된 공개 키와 일치하는지 보장해야 MUST 한다.

6.1. JWK 지문 확인 방법

액세스 토큰이 JWT [RFC7519]로 표현되는 경우, 공개 키 정보는 여기서 정의하는 jkt 확인 방법 멤버를 사용하여 표현된다. JWT에서 공개 키의 해시를 전달하기 위해, 이 명세는 cnf 클레임 아래에서 사용할 다음 JWT Confirmation Method [RFC7800] 멤버를 도입한다.

jkt:
JWK SHA-256 지문 확인 방법. jkt 멤버의 값은 액세스 토큰이 바인딩된 DPoP 공개 키(JWK 형식)의 JWK SHA-256 지문([RFC7638]에 따름)을 base64url 인코딩([RFC7515]에 정의됨)한 값이어야 MUST 한다.

그림 8의 다음 예제 JWT와 그림 9에 표시된 디코딩된 JWT 페이로드는 jkt JWK 지문 확인 방법 멤버가 있는 cnf 클레임을 포함한다. 이 예제들의 jkt 값은 섹션 5에 표시된 예제의 DPoP 증명에 있는 공개 키의 해시이다. 이 예제는 [RFC8792]에 따른 "\" 줄바꿈을 사용한다.

eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWIiOiJzb21lb25lQGV4YW1\
wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJuYmYiOjE\
1NjIyNjI2MTEsImV4cCI6MTU2MjI2NjIxNiwiY25mIjp7ImprdCI6IjBaY09DT1JaTll\
5LURXcHFxMzBqWnlKR0hUTjBkMkhnbEJWM3VpZ3VBNEkifX0.3Tyo8VTcn6u_PboUmAO\
YUY1kfAavomW_YwYMkmRNizLJoQzWy2fCo79Zi5yObpIzjWb5xW4OGld7ESZrh0fsrA
그림 8: JWK SHA-256 지문 확인을 포함하는 JWT
{
  "sub":"someone@example.com",
  "iss":"https://server.example.com",
  "nbf":1562262611,
  "exp":1562266216,
  "cnf":
  {
    "jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
  }
}
그림 9: JWK SHA-256 지문 확인이 있는 JWT 클레임 집합

6.2. 토큰 인트로스펙션에서의 JWK 지문 확인 방법

"OAuth 2.0 Token Introspection" [RFC7662]은 보호된 리소스가 액세스 토큰의 활성 상태에 대해 인가 서버에 질의하는 방법을 정의한다. 보호된 리소스는 토큰에 관한 메타정보도 결정한다.

DPoP 바인딩 액세스 토큰의 경우, 토큰이 바인딩된 공개 키의 해시는 토큰 인트로스펙션 응답에서 메타정보로 보호된 리소스에 전달된다. 이 해시는 섹션 6.1에 설명된 JWK 지문 확인 방법과 동일한 jkt 멤버 구조의 cnf 콘텐츠를 인트로스펙션 응답 JSON의 최상위 멤버로 사용하여 전달된다. 리소스 서버는 인트로스펙션 요청과 함께 DPoP 증명을 보내지 않으며, 인가 서버는 인트로스펙션 엔드포인트에서 액세스 토큰의 DPoP 바인딩을 검증하지 않는다는 점에 유의한다. 대신, 리소스 서버는 인트로스펙션 응답의 데이터를 사용하여 액세스 토큰 바인딩을 자체적으로 로컬에서 검증한다.

인트로스펙션 응답에 token_type 멤버가 포함된 경우, 그 값은 DPoP를 포함해야 MUST 한다.

그림 10의 예제 인트로스펙션 요청과 그림 11의 해당 응답은 그림 6에서 발급된 예제 DPoP 바인딩 액세스 토큰에 대한 인트로스펙션 교환을 예시한다.

POST /as/introspect.oauth2 HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic cnM6cnM6TWt1LTZnX2xDektJZHo0ZnNON2tZY3lhK1Rp

token=Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
그림 10: 예제 인트로스펙션 요청
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "active": true,
  "sub": "someone@example.com",
  "iss": "https://server.example.com",
  "nbf": 1562262611,
  "exp": 1562266216,
  "cnf":
  {
    "jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
  }
}
그림 11: DPoP 바인딩 액세스 토큰에 대한 예제 인트로스펙션 응답

7. 보호된 리소스 접근

DPoP 보호 리소스에 대한 요청은 섹션 4에 따른 DPoP 증명과 섹션 7.1에 설명된 액세스 토큰을 모두 포함해야 MUST 한다. DPoP 증명은 관련 액세스 토큰의 유효한 해시가 있는 ath 클레임을 포함해야 MUST 한다.

이 방식으로 토큰 값을 증명에 바인딩하면 하나의 증명이 서로 다른 요청에서 여러 다른 액세스 토큰 값과 함께 사용되는 것을 방지한다. 예를 들어, 클라이언트가 서로 다른 두 리소스 소유자에게 바인딩된 토큰 AT1과 AT2를 보유하고, 인가 서버와 통신할 때 동일한 키를 사용하는 경우, 이러한 토큰이 서로 교체될 가능성이 있다. 이를 바인딩하는 ath 필드가 없으면, AT1에 적용된 캡처된 서명이 대신 AT2와 함께 재전송되어 의도된 요청의 권한과 접근이 변경될 수 있다. 동일한 대체 방지는 같은 클라이언트와 리소스 소유자 조합 내에서 순환된 액세스 토큰에도 유지된다. 순환된 토큰 값에는 새 증명의 계산이 필요하다. 또한 이 바인딩은 액세스 토큰과 함께 사용하기 위한 증명이 액세스 토큰 없이 사용할 수 없고, 그 반대도 사용할 수 없음을 보장한다.

리소스 서버는 제시된 토큰 값의 해시를 계산하고, 섹션 4.3에 설명된 것처럼 그것이 ath 필드의 해시 값과 동일한지 검증해야 한다. ath 필드 값은 DPoP 증명의 서명에 의해 포괄되므로, 그 포함은 액세스 토큰 값을 서명을 생성하는 데 사용된 키의 보유자에게 바인딩한다.

ath 필드만으로는 DPoP 증명의 재전송을 방지하거나 그 증명이 제시된 요청에 대한 바인딩을 제공하지 않는다는 점에 유의한다. 따라서 htmhtu와 같은 포함된 메시지 매개변수뿐 아니라 증명의 시간 창을 확인하는 것도 여전히 중요하다.

7.1. DPoP 인증 스킴

DPoP 바인딩 액세스 토큰은 DPoP 인증 스킴과 함께 섹션 11.6.2 of [RFC9110]에 따른 Authorization 요청 헤더 필드를 사용하여 전송된다. DPoP 스킴에 대한 Authorization 헤더 필드의 구문은 자격 증명에 대해 섹션 11.2 of [RFC9110]에 정의된 token68 구문을 사용하며, 참조의 편의를 위해 아래에 다시 제시한다. DPoP 인증 스킴 자격 증명에 대한 ABNF 표기법 구문은 다음과 같다.

token68    = 1*( ALPHA / DIGIT /
                 "-" / "." / "_" / "~" / "+" / "/" ) *"="

credentials = "DPoP" 1*SP token68
그림 12: DPoP 인증 스킴 ABNF

그러한 액세스 토큰의 경우, 리소스 서버는 HTTP 요청의 DPoP 헤더 필드에서 DPoP 증명도 수신되었는지 확인하고, 섹션 4.3의 규칙에 따라 DPoP 증명을 확인하며, DPoP 증명의 공개 키가 섹션 6에 따라 액세스 토큰이 바인딩된 공개 키와 일치하는지 확인해야 MUST 한다.

리소스 서버는 모든 검사가 성공하지 않는 한 리소스에 대한 접근을 허용해서는 안 된다 MUST NOT.

그림 13Authorization 헤더에 DPoP 바인딩 액세스 토큰을, DPoP 헤더에 DPoP 증명을 포함한 보호된 리소스에 대한 예제 요청을 보여준다. 이 예제는 [RFC8792]에 따른 "\" 줄바꿈을 사용한다. 그림 14는 해당 DPoP 증명의 디코딩된 내용을 보여준다. JWT 헤더와 페이로드의 JSON은 표시하지만, 서명 부분은 생략했다. 일반적으로 줄바꿈과 들여쓰기는 형식 지정과 가독성을 위해 포함되어 있다.

GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj\
 oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z\
 WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF\
 c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E\
 OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA
그림 13: DPoP 보호 리소스 요청
{
  "typ":"dpop+jwt",
  "alg":"ES256",
  "jwk": {
    "kty":"EC",
    "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
    "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
    "crv":"P-256"
  }
}
.
{
  "jti":"e1j3V_bKic8-LAEB",
  "htm":"GET",
  "htu":"https://resource.example.org/protectedresource",
  "iat":1562262618,
  "ath":"fUHyO2r2Z3DZ53EsNrWBb0xWXoaNy59IiKCAqksmQEo"
}
그림 14: 그림 13의 DPoP 증명 JWT 디코딩 내용

DPoP 인증이 필요한 보호 공간 내의 보호된 리소스에 대한 요청을 수신하면, 서버는 요청이 유효한 자격 증명을 포함하지 않거나 접근에 충분한 액세스 토큰을 포함하지 않는 경우, 클라이언트가 DPoP 인증 정보를 제공하도록 챌린지로 응답할 수 있다. 이러한 챌린지는 401 (Unauthorized) 응답 상태 코드 ([RFC9110], 섹션 15.5.2)와 WWW-Authenticate 헤더 필드 ([RFC9110], 섹션 11.6.1)를 사용하여 이루어진다. 서버는 다른 조건에 대한 응답으로도 WWW-Authenticate 헤더를 포함할 수 있다 MAY.

그러한 챌린지에서:

  • 스킴 이름은 DPoP이다.
  • 인증 매개변수 realm[RFC9110], 섹션 11.5에 설명된 방식으로 보호 범위를 나타내기 위해 포함될 수 있다 MAY.
  • scope 인증 매개변수는 [RFC6750], 섹션 3에 정의된 대로 포함될 수 있다 MAY.
  • error 매개변수 ([RFC6750], 섹션 3)는 요청에 액세스 토큰이 포함되어 있었지만 인증에 실패한 경우, 요청이 거부된 이유를 나타내기 위해 포함되어야 SHOULD 한다. [RFC6750], 섹션 3.1에 설명된 오류 매개변수 값이 적합하며, 확장에 의해 정의된 적절한 값도 사용할 수 있다. use_dpop_nonce 값은 후속 요청의 DPoP 증명에 nonce가 필요함을 신호하기 위해 섹션 9에 설명된 대로 사용할 수 있다. 또한 invalid_dpop_proof는 DPoP 증명 자체가 섹션 4.3의 기준에 따라 유효하지 않은 것으로 판단되었음을 나타내는 데 사용된다.
  • error_description 매개변수 ([RFC6750], 섹션 3)는 최종 사용자에게 표시하기 위한 것이 아닌 개발자용 사람이 읽을 수 있는 설명을 제공하기 위해 error 매개변수와 함께 포함될 수 있다 MAY.
  • algs 매개변수는 DPoP 증명 JWT에 허용 가능한 JWS 알고리즘을 클라이언트에 신호하기 위해 포함되어야 SHOULD 한다. 이 매개변수의 값은 공백으로 구분된 JWS alg(Algorithm) 헤더 값 목록이다([RFC7515], 섹션 4.1.1).
  • 추가 인증 매개변수를 사용할 수 있으며 MAY, 수신자는 알 수 없는 매개변수를 무시해야 MUST 한다.

그림 15는 인증 없이 보호된 리소스에 대한 요청에 대한 응답을 보여준다.

 HTTP/1.1 401 Unauthorized
 WWW-Authenticate: DPoP algs="ES256 PS256"
그림 15: 인증 없는 보호된 리소스 요청에 대한 HTTP 401 응답

그림 16은 액세스 토큰의 DPoP 바인딩 확인 실패로 인해 거부된 보호된 리소스 요청에 대한 응답을 보여준다. 그림 16[RFC8792]에 따른 "\" 줄바꿈을 사용한다.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: DPoP error="invalid_token", \
   error_description="Invalid DPoP key binding", algs="ES256"
그림 16: 유효하지 않은 토큰이 있는 보호된 리소스 요청에 대한 HTTP 401 응답

Cross-Origin Resource Sharing(CORS) [WHATWG.Fetch]을 사용하는 브라우저 기반 클라이언트 애플리케이션은 기본적으로 CORS 안전 목록 응답 HTTP 헤더에만 접근할 수 있다는 점에 유의한다. 애플리케이션이 WWW-Authenticate HTTP 응답 헤더 값을 얻고 사용할 수 있도록 하려면, 서버는 Access-Control-Expose-Headers 응답 헤더 목록 값에 WWW-Authenticate를 포함하여 이를 애플리케이션에서 사용할 수 있게 해야 한다.

이 인증 스킴은 오리진 서버 인증 전용이다. 따라서 이 인증 스킴은 Proxy-Authenticate 또는 Proxy-Authorization 헤더 필드와 함께 사용되어서는 안 된다 MUST NOT.

이 인증 스킴의 Authorization 헤더 필드 구문은 섹션 2.1 of [RFC6750]에 정의된 Bearer 스킴의 사용을 따른다는 점에 유의한다. 이는 [RFC9110]의 선호 자격 증명 구문은 아니지만, 그 안의 일반 인증 프레임워크와 호환되며 Bearer 스킴과의 일관성과 친숙성을 위해 사용된다.

7.2. Bearer 인증 스킴과의 호환성

DPoPBearer 스킴을 동시에 지원하는 보호된 리소스는 DPoP 바인딩 액세스 토큰의 다운그레이드된 사용을 방지하기 위해 베어러 토큰에 대한 평가 과정 수행 방식을 업데이트해야 한다. 구체적으로, 그러한 보호된 리소스는 [RFC6750]에 따라 베어러 토큰으로 수신된 DPoP 바인딩 액세스 토큰을 거부해야 MUST 한다.

섹션 11.6.1 of [RFC9110]은 보호된 리소스가 401 (Unauthorized) 응답의 WWW-Authenticate 헤더 필드를 통해 여러 인증 스킴(즉, BearerDPoP)에 대한 지원을 나타낼 수 있도록 허용한다.

[RFC6750]만 지원하고 DPoP를 인식하지 못하는 보호된 리소스는 DPoP 바인딩 액세스 토큰을 베어러 토큰으로 받아들일 가능성이 가장 높다 (JWT [RFC7519]는 인식하지 못하는 클레임을 무시하라고 말하고, Introspection [RFC7662]은 다른 매개변수가 존재할 수 있다고 하면서도 그 존재에 대한 기능적 요구사항을 두지 않으며, [RFC6750]은 유효성과 관련된 액세스 토큰의 내용에 대해 사실상 침묵하고 있기 때문이다). 따라서 클라이언트는 보호된 리소스로부터 WWW-Authenticate: Bearer 챌린지를 수신하면 Bearer 스킴을 사용하여 DPoP 바인딩 액세스 토큰을 보낼 수 있다 (또는 보호된 리소스의 기능을 사전에 알고 있는 경우 DPoP 바인딩 액세스 토큰을 보낼 수 있다). 이 효과는 보호된 리소스가 DPoP 지원으로 단계적으로 업그레이드되거나, 혼합 토큰 유형 지원을 가진 보호된 리소스가 장기간 배포되는 과정의 실무를 단순화할 가능성이 높다.

BearerDPoP 스킴을 모두 지원하는 보호된 리소스가 여러 WWW-Authenticate 챌린지로 응답하기로 선택한 경우, 실제 오류 정보를 어떤 챌린지가 전달해야 하는지에 주의를 기울여야 한다. 다음 규칙을 준수하는 것이 RECOMMENDED된다.

  • 요청에 인증 정보가 포함되어 있지 않은 경우, 챌린지는 섹션 3.1 of [RFC6750]에 따라 오류 코드 또는 기타 오류 정보를 포함하지 않아야 SHOULD NOT 한다 (그림 17).

  • 인증을 시도하는 데 사용된 메커니즘이 명확하게 확정될 수 있는 경우, 해당 챌린지를 사용하여 오류 정보를 전달해야 SHOULD 한다 (그림 18).

  • 그렇지 않으면, BearerDPoP 챌린지 모두를 사용하여 오류 정보를 전달할 수 있다 MAY (그림 19).

다음 예제들은 [RFC8792]에 따른 "\" 줄바꿈을 사용한다.

GET /protectedresource HTTP/1.1
Host: resource.example.org

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer, DPoP algs="ES256 PS256"
그림 17: 인증 없는 보호된 리소스 요청에 대한 HTTP 401 응답
GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: Bearer INVALID_TOKEN

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token", \
    error_description="Invalid token", DPoP algs="ES256 PS256"
그림 18: 유효하지 않은 인증이 있는 보호된 리소스 요청에 대한 HTTP 401 응답
GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: Bearer Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU

HTTP/1.1 400 Bad Request
WWW-Authenticate: Bearer error="invalid_request", \
 error_description="Multiple methods used to include access token", \
 DPoP algs="ES256 PS256", error="invalid_request", \
 error_description="Multiple methods used to include access token"
그림 19: 모호한 인증이 있는 보호된 리소스 요청에 대한 HTTP 400 응답

7.3. 클라이언트 고려사항

DPoP 증명을 포함한 인가는 (서버의 jti, iat, 및 nonce 클레임 적용 방식에 따라) 멱등적이지 않을 수 있다. 결과적으로, 이전에 멱등적이었던 보호된 리소스에 대한 모든 요청은 더 이상 멱등적이지 않을 수 있다. 일반적으로 일시적인 것으로 이해되는 HTTP 오류에 대한 응답으로 멱등 요청을 재시도하는 경우에도, 클라이언트가 고유한 DPoP 증명을 생성하는 것이 RECOMMENDED된다.

빈번한 네트워크 오류를 겪는 클라이언트는 더 엄격한 nonce 검증 구현을 가진 서버와 상호작용할 때 추가적인 어려움을 경험할 수 있다.

8. 인가 서버 제공 Nonce

이 절은 서버가 제공하는 불투명 nonce를 사용하는 메커니즘을 명시하며, 이는 DPoP 증명의 수명을 제한하는 데 사용할 수 있다. 이러한 메커니즘을 사용하지 않으면, 클라이언트를 제어하는 악의적인 당사자 (잠재적으로 최종 사용자를 포함)는 임의로 먼 미래에 사용할 DPoP 증명을 만들 수 있다.

인가 서버가 제공한 nonce 값을 DPoP 증명에 포함하는 것은 인가 서버가 DPoP 증명의 수명을 제한하는 데 사용할 수 있다 MAY. 서버는 새로운 DPoP nonce 챌린지를 언제 발행할지와 그것이 필요한지를 결정하며, 그에 따라 이후 DPoP 증명에서 nonce 값의 사용을 요구한다. 서버가 그러한 결정을 내리는 로직은 이 문서의 범위를 벗어난다.

인가 서버는 클라이언트가 보낸 DPoP 증명에 포함할 nonce 값을 제공할 수 있다 MAY. 이 경우, 인가 서버는 nonce를 포함하지 않은 요청에 대해 섹션 5.2 of [RFC6749]에 따라 오류 코드 값으로 use_dpop_nonce를 사용한 HTTP 400 (Bad Request) 오류 응답으로 응답한다. 인가 서버는 이후 요청을 보낼 때 사용할 nonce 값을 제공하는 DPoP-Nonce HTTP 헤더를 응답에 포함한다. Nonce 값은 예측 불가능해야 MUST 한다. nonce 불일치가 있었을 때 새 nonce 값을 제공하는 경우에도 동일한 오류 코드가 사용된다. 클라이언트는 일반적으로 nonce 값이 함께 제공된 use_dpop_nonce 오류를 수신하면, 제공된 새 nonce 값으로 요청을 재시도한다.

예를 들어, 인가 서버가 nonce를 요구할 때 nonce 없는 토큰 요청에 응답하여, 인가 서버는 다음과 같은 DPoP-Nonce 값을 반환하여 DPoP 증명에 포함할 nonce 값을 제공할 수 있다.

 HTTP/1.1 400 Bad Request
 DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v

 {
  "error": "use_dpop_nonce",
  "error_description":
    "Authorization server requires nonce in DPoP proof"
 }
그림 20: Nonce 없는 토큰 요청에 대한 HTTP 400 응답

오류 응답에는 다른 HTTP 헤더 및 JSON 필드도 포함될 수 있지만 MAY, DPoP-Nonce 헤더는 둘 이상 있어서는 안 된다 MUST NOT.

nonce를 수신하면, 클라이언트는 제공된 nonce 값을 DPoP 증명의 nonce 클레임에 포함한 DPoP 증명을 사용하여 토큰 요청을 재시도할 것으로 기대된다. nonce를 포함한 그러한 DPoP 증명의 인코딩되지 않은 JWT 페이로드 예제가 아래에 표시되어 있다.

 {
  "jti": "-BwC3ESc6acc2lTc",
  "htm": "POST",
  "htu": "https://server.example.com/token",
  "iat": 1562262616,
  "nonce": "eyJ7S_zG.eyJH0-Z.HX4w-7v"
 }
그림 21: Nonce 값을 포함한 DPoP 증명 페이로드

nonce는 클라이언트에게 불투명하다.

DPoP 증명의 nonce 클레임이 인가 서버가 최근 클라이언트에 제공한 nonce와 정확히 일치하지 않으면, 인가 서버는 요청을 거부해야 MUST 한다. 거부 응답에는 이후 요청에 사용할 새 nonce 값을 제공하는 DPoP-Nonce HTTP 헤더가 포함될 수 있다 MAY.

의도는 클라이언트가 하나의 nonce 값만 유지하면 되고 서버는 최근 nonce의 창을 유지하면 된다는 것이다. 그렇지만 서버와 클라이언트가 저장한 nonce 값이 서로 다른 일시적 상황이 발생할 수 있다. 그러나 이 상황은 자체적으로 보정된다. 어떤 거부 메시지에서든, 서버는 자신이 사용하기 원하는 nonce 값을 클라이언트에 보낼 수 있고, 클라이언트는 그 nonce 값을 저장한 뒤 그것으로 요청을 재시도할 수 있다. 클라이언트 및/또는 서버가 저장된 nonce 값을 폐기하더라도, 실패한 요청에 응답하거나 재시도할 때 새 nonce 값을 전달할 수 있으므로 그 상황도 자체적으로 보정된다.

CORS [WHATWG.Fetch]를 사용하는 브라우저 기반 클라이언트 애플리케이션은 기본적으로 CORS 안전 목록 응답 HTTP 헤더에만 접근할 수 있다는 점에 유의한다. 애플리케이션이 DPoP-Nonce HTTP 응답 헤더 값을 얻고 사용할 수 있도록 하려면, 서버는 Access-Control-Expose-Headers 응답 헤더 목록 값에 DPoP-Nonce를 포함하여 이를 애플리케이션에서 사용할 수 있게 해야 한다.

8.1. Nonce 구문

[RFC6749]에서 사용하는 ABNF의 nonce 구문 (scope-token 구문과 동일함)은 아래와 같다.

nonce = 1*NQCHAR
그림 22: Nonce ABNF

8.2. 새 Nonce 값 제공

클라이언트가 사용할 새 nonce 값을 언제 제공할지는 인가 서버에 달려 있다. 클라이언트는 인가 서버가 새 nonce 값을 제공할 때까지 기존에 제공된 nonce를 DPoP 증명에 사용할 것으로 기대된다.

인가 서버는 최초 nonce가 제공된 것과 동일한 방식, 즉 응답에 DPoP-Nonce HTTP 헤더를 사용하여 새 nonce를 제공할 수 있다 MAY. DPoP-Nonce HTTP 헤더 필드는 섹션 8.1에 정의된 nonce 구문을 사용한다. 이 일이 발생할 때마다 추가 프로토콜 왕복이 필요하다.

새 nonce 값을 제공하는 더 효율적인 방식도 정의되어 있는데, 이전 요청에 대한 HTTP 200 (OK) 응답에 DPoP-Nonce HTTP 헤더를 포함하는 것이다. 클라이언트는 제공된 새 nonce 값을 다음 토큰 요청과 인가 서버가 새 nonce를 제공할 때까지의 모든 이후 토큰 요청에 사용해야 MUST 한다.

DPoP-Nonce HTTP 헤더를 포함하는 응답은 응답이 이후 요청을 처리하는 데 사용되고 그 결과 오래된 nonce 값이 사용되는 것을 방지하기 위해 캐시 불가능해야 한다 (예: GET 요청에 대한 응답에서 Cache-Control: no-store 사용).

새 nonce 값을 제공하는 예제 200 OK 응답은 아래와 같다.

 HTTP/1.1 200 OK
 Cache-Control: no-store
 DPoP-Nonce: eyJ7S_zG.eyJbYu3.xQmBj-1
그림 23: 다음 Nonce 값을 제공하는 HTTP 200 응답

9. 리소스 서버 제공 Nonce

리소스 서버도 자신에게 전송되는 DPoP 증명에 포함할 nonce 값을 제공하도록 선택할 수 있다. 리소스 서버는 8절 및 8.2절에 설명된 것처럼 인가 서버와 같은 방식으로 DPoP-Nonce 헤더를 사용하여 nonce를 제공한다. 오류 신호 전달은 섹션 7.1에 설명된 대로 수행된다. 리소스 서버는 이를 위해 HTTP 401 (Unauthorized) 오류 코드와 함께 WWW-Authenticate: DPoP 값 및 DPoP-Nonce 값을 사용한다.

예를 들어, 리소스 서버가 nonce를 요구할 때 nonce 없는 리소스 요청에 응답하여, 리소스 서버는 다음과 같은 DPoP-Nonce 값을 반환하여 DPoP 증명에 포함할 nonce 값을 제공할 수 있다. 아래 예제는 [RFC8792]에 따른 "\" 줄바꿈을 사용한다.

 HTTP/1.1 401 Unauthorized
 WWW-Authenticate: DPoP error="use_dpop_nonce", \
   error_description="Resource server requires nonce in DPoP proof"
 DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v
그림 24: Nonce 없는 리소스 요청에 대한 HTTP 401 응답

인가 서버와 리소스 서버가 제공하는 nonce는 서로 다르며, nonce는 그것을 발행한 서버에서만 수락되므로 서로 혼동해서는 안 된다는 점에 유의한다. 마찬가지로, 클라이언트가 여러 인가 서버 및/또는 리소스 서버를 사용하는 경우, 그중 하나가 발행한 nonce는 발행 서버에서만 사용해야 한다. 개발자는 DPoP nonce를 OpenID Connect [OpenID.Core] ID Token nonce와 혼동하지 않도록 주의해야 한다.

10. 인가 코드의 DPoP 키 바인딩

클라이언트의 소유 증명 키에 발급된 인가 코드를 바인딩하면 전체 인가 흐름의 종단 간 바인딩을 가능하게 할 수 있다. 이 명세는 이를 위해 dpop_jkt 인가 요청 매개변수를 정의한다. dpop_jkt 인가 요청 매개변수의 값은 SHA-256 해시 함수를 사용하는 소유 증명 공개 키의 JWK Thumbprint [RFC7638]이며, 이는 섹션 6.1에 정의된 jkt 확인 방법에 사용되는 값과 동일하다.

토큰 요청이 수신되면, 인가 서버는 DPoP 증명의 소유 증명 공개 키에 대한 JWK Thumbprint를 계산하고, 그것이 인가 요청의 dpop_jkt 매개변수 값과 일치하는지 검증한다. 일치하지 않으면, 요청을 거부해야 MUST 한다.

dpop_jkt 인가 요청 매개변수를 사용하는 예제 인가 요청은 아래에 표시되어 있으며, [RFC8792]에 따른 "\" 줄바꿈을 사용한다.

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz\
    &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\
    &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM\
    &code_challenge_method=S256\
    &dpop_jkt=NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs HTTP/1.1
Host: server.example.com
그림 25: dpop_jkt 매개변수를 사용하는 인가 요청

dpop_jkt 인가 요청 매개변수의 사용은 OPTIONAL이다. dpop_jkt 인가 요청 매개변수는 인가 코드 주입에 대한 대응책으로 [SECURITY-TOPICS]가 권장하는 Proof Key for Code Exchange(PKCE) [RFC7636]와 함께 사용될 수도 있음에 유의한다 MAY. dpop_jkt 인가 요청 매개변수는 각 인가 요청에 고유한 DPoP 키가 사용되는 경우에만 유사한 보호를 제공한다.

10.1. 푸시된 인가 요청과 DPoP

Pushed Authorization Requests(PARs) [RFC9126]가 DPoP와 함께 사용되는 경우, PAR 요청에서 DPoP 키를 전달할 수 있는 방법은 두 가지가 있다.

  • dpop_jkt 매개변수는 발급된 인가 코드를 특정 키에 바인딩하기 위해 섹션 10에 설명된 대로 사용할 수 있다. 이 경우, dpop_jkt는 PAR 요청의 POST 본문에서 다른 인가 요청 매개변수와 함께 포함되어야 MUST 한다.
  • 또는 DPoP 헤더를 PAR 요청에 추가할 수 있다. 이 경우, 인가 서버는 섹션 4.3에 정의된 대로 제공된 DPoP 증명 JWT를 확인해야 MUST 한다. 또한 포함된 공개 키의 지문이 dpop_jkt를 사용해 제공된 것처럼 동작해야 MUST 한다. 즉, 동일한 키에 대한 DPoP 증명이 제공되지 않으면 이후 토큰 요청을 거부해야 한다. 이는 클라이언트가 요청 유형과 관계없이 인가 서버로 가는 모든 요청에 DPoP 헤더를 "맹목적으로" 첨부할 수 있게 하므로 클라이언트 구현을 단순화하는 데 도움이 될 수 있다. 또한 DPoP 헤더가 개인 키의 소유 증명을 포함하므로 더 강한 바인딩을 제공한다.

PAR와 DPoP를 지원하는 인가 서버는 두 메커니즘을 모두 지원해야 MUST 한다. 두 메커니즘이 동시에 사용되는 경우, dpop_jkt의 JWK Thumbprint가 DPoP 헤더의 공개 키와 일치하지 않으면 인가 서버는 요청을 거부해야 MUST 한다.

두 메커니즘을 모두 허용하면 dpop_jkt를 사용하는 클라이언트가 프런트 채널 요청과 푸시된 인가 요청을 구분할 필요가 없으며, 동시에 인가 서버 엔드포인트에 대한 모든 호출을 보호하는 코드 경로가 하나뿐인 클라이언트가 PAR 엔드포인트에 대한 요청과 토큰 엔드포인트에 대한 요청을 구분할 필요도 없게 된다.

11. 보안 고려사항

DPoP에서 다른 엔드포인트에서의 토큰 재전송 방지 (섹션 2 참조)는 [RFC6125]에 따른 서버 인증과 DPoP 증명을 특정 URI 및 HTTP 메서드에 바인딩함으로써 달성된다. 그러나 DPoP는 OAuth Mutual TLS [RFC8705] 또는 OAuth Token Binding [TOKEN-BINDING] 같은 TLS 기반 방식과는 다소 다른 보호 특성을 가진다(11.1절 및 11.7절도 참조). TLS 기반 메커니즘은 TLS 계층과 애플리케이션 계층 간의 긴밀한 통합을 활용하여 강한 메시지 무결성, 진정성, 및 재전송 보호를 달성할 수 있다.

11.1. DPoP 증명 재전송

공격자가 DPoP 증명 JWT를 입수할 수 있다면, 공격자는 동일한 엔드포인트에서 그 토큰을 재전송할 수 있다(HTTP 엔드포인트와 메서드는 JWT의 해당 클레임을 통해 강제된다). 이를 제한하기 위해, 서버는 생성 후 제한된 시간 동안만 DPoP 증명을 수락해야 MUST 한다(가급적 초 또는 분 단위의 비교적 짧은 기간).

대상 URI의 컨텍스트에서, 서버는 동일한 DPoP 증명의 여러 사용을 방지하기 위해 해당 DPoP 증명 JWT가 수락되는 시간 창 동안 각 DPoP 증명의 jti 값을 저장할 수 있다. 동일한 URI에 대한 HTTP 요청 중 이전에 본 jti 값을 가진 요청은 거부된다. 엄격하게 적용되는 경우, 이러한 단일 사용 검사는 DPoP 증명 재전송에 대해 매우 강력한 보호를 제공하지만, 예를 들어 단일 엔드포인트 뒤의 여러 서버가 공유 상태를 갖지 않는 경우처럼 실제로 항상 실현 가능하지는 않을 수 있다.

메모리 고갈 공격을 방지하기 위해, jti 값을 추적하는 서버는 불필요하게 큰 jti 값을 가진 DPoP 증명 JWT를 거부하거나 그 해시만 저장해야 한다.

참고: 시계 오프셋을 수용하기 위해, 서버는 합리적으로 가까운 미래 (초 또는 분 단위)의 iat 시간을 포함하는 DPoP 증명을 수락할 수 있다 MAY. 서버와 클라이언트 간의 시계 차이가 클 수 있으므로, 서버는 클라이언트가 제공한 iat 시간을 서버의 시간과 비교하는 대신, 서버 시간을 포함하는 서버 제공 nonce 값을 사용하여 DPoP 증명 수명을 제한할 수 있다 MAY. 이러한 방식으로 생성된 nonce는 임의로 큰 시계 차이가 있더라도 동일한 결과를 낸다.

서버 제공 nonce는 성공적인 DPoP 증명 재전송 가능성을 추가로 줄이는 효과적인 수단이다. 암호학적 nonce와 달리, 클라이언트가 동일한 nonce를 여러 번 사용하고 서버가 동일한 nonce를 여러 번 수락하는 것은 허용된다. jti 값이 추적되고 nonce의 수명 동안 중복이 거부되는 한, 토큰 재전송에 대한 추가 위험은 없다.

11.2. DPoP 증명 사전 생성

클라이언트를 제어하는 공격자는 DPoP 증명에서 소유 증명 키로 서명될 iat 값을 선택함으로써, 특정 엔드포인트에 대한 DPoP 증명을 임의로 먼 미래까지 사전 생성할 수 있다. 이러한 공격자 중 하나가 클라이언트의 정당한 사용자일 수 있다는 점에 유의한다. 사용자는 DPoP 증명을 사전 생성하여, 그것이 생성된 소유 증명 키를 가진 머신에서 유출하고, 키를 소유하지 않은 다른 머신으로 복사할 수 있다. 예를 들어, 은행 직원이 은행 컴퓨터에서 DPoP 증명을 사전 생성한 다음 향후 사용하기 위해 다른 머신으로 복사하여 은행 감사 통제를 우회할 수 있다. DPoP 증명을 사전 생성하고 유출할 수 있는 경우, DPoP 프로토콜 상호작용에서 실제로 증명되는 것은 소유 증명 키의 소유가 아니라 DPoP 증명의 소유이다.

공격자가 예측할 수 없는 서버 제공 nonce 값을 사용하면 이 공격을 방지할 수 있다. 서버는 자신이 선택한 시점에 새 nonce 값을 제공함으로써 DPoP 증명의 수명을 제한하고, 사전 생성된 DPoP 증명이 사용되는 것을 방지할 수 있다. 서버 제공 nonce가 사용되면, 단지 DPoP 증명의 소유가 아니라 소유 증명 키의 소유가 입증된다.

ath 클레임은 사전 생성된 DPoP 증명의 사용을 액세스 토큰의 수명으로 제한한다. nonce 메커니즘을 활용하지 않는 배포는 장기 수명의 DPoP 제한 액세스 토큰을 발급해서는 안 되며 SHOULD NOT, 대신 단기 수명의 액세스 토큰과 리프레시 토큰을 사용하는 것이 바람직하다. 공격자는 리프레시 토큰을 사용하여 새 액세스 토큰을 얻기 위한 DPoP 증명을 사전 생성할 수는 있지만, 새로 발급된 액세스 토큰을 사용하기 위한 DPoP 증명을 현실적으로 사전 생성할 수는 없다.

11.3. DPoP Nonce 다운그레이드

서버는 클라이언트에 DPoP nonce가 제공된 경우, nonce 클레임이 없는 어떤 DPoP 증명도 수락해서는 안 된다 MUST NOT.

11.4. 클라이언트 컨텍스트의 신뢰할 수 없는 코드

공격자가 클라이언트의 실행 컨텍스트에서 코드를 실행할 수 있다면, DPoP의 보안은 더 이상 보장되지 않는다. 신뢰할 수 없는 코드 실행으로 이어지는 웹 애플리케이션의 일반적인 문제에는 XSS와 원격 코드 포함 공격이 있다.

DPoP에 사용되는 개인 키가 하드웨어 또는 소프트웨어 보안 모듈처럼 내보낼 수 없는 방식으로 저장된 경우, 공격자는 키를 유출하여 임의의 DPoP 증명을 만드는 데 사용할 수 없다. 그러나 공격자는 클라이언트가 온라인인 동안 새 DPoP 증명을 만들 수 있으며, 이러한 증명(및 해당 토큰)을 피해자의 장치 또는 공격자가 제어하는 장치에서 사용하여 서버가 수락할 임의의 요청을 보낼 수 있다.

클라이언트가 오프라인일 때도 요청을 보내기 위해, 공격자는 미래의 타임스탬프를 사용하여 DPoP 증명을 미리 계산하고, 이를 액세스 토큰 또는 리프레시 토큰과 함께 유출하려고 시도할 수 있다.

공격자는 토큰 엔드포인트에서 발급된 토큰을 공격자가 제어하는 키 쌍과 연결하려고 더 시도할 수 있다. 이를 달성하는 한 가지 방법은 예를 들어 암호화 API를 교체하는 방식으로 기존 코드를 수정하는 것이다. 또 다른 방법은 iframe에서 클라이언트와 인가 서버 간의 새 인가 그랜트를 시작하는 것이다. 이 그랜트는 "silent"해야 하며, 즉 사용자와의 상호작용을 요구하지 않아야 한다. 클라이언트의 origin에서 코드가 실행되면, 공격자는 결과 인가 코드에 접근할 수 있고 이를 사용하여 자신의 DPoP 키를 토큰 엔드포인트에서 반환된 토큰과 연결할 수 있다. 그러면 공격자는 클라이언트가 오프라인일 때도 결과 토큰을 자신의 장치에서 사용할 수 있다.

따라서 DPoP가 사용되더라도 신뢰할 수 없는 코드의 실행으로부터 클라이언트를 보호하는 것은 매우 중요하다. 보안 코딩 관행 외에도, Content Security Policy [W3C.CSP]를 XSS에 대한 두 번째 방어 계층으로 사용할 수 있다.

11.5. 서명된 JWT 교체

서명된 DPoP 증명 JWT를 수락하는 서버는 공격자가 다른 목적으로 생성된 JWT를 사용할 수 없도록, JWT 헤더의 typ 필드가 dpop+jwt인지 검증해야 MUST 한다.

11.6. 서명 알고리즘

구현자는 안전하다고 판단되는 비대칭 디지털 서명 알고리즘 (예: ES256)만 DPoP 증명 서명에 사용할 수 있도록 보장해야 MUST 한다. 특히, none 알고리즘은 허용되어서는 안 된다 MUST NOT.

11.7. 요청 무결성

DPoP는 요청의 페이로드나 헤더의 무결성을 보장하지 않는다. DPoP 증명은 예를 들어 HTTP URI와 메서드에 대한 클레임만 포함하고, 메시지 본문이나 일반 요청 헤더는 포함하지 않는다.

이는 DPoP를 사용하기 쉽게 유지하려는 의도적인 설계 결정이지만, 설명한 것처럼 공격자가 메시지 내용과 헤더를 수정할 수 있는 경우 DPoP가 재전송 공격에 잠재적으로 취약해진다. 많은 설정에서는 TLS가 제공하는 메시지 무결성과 기밀성이 충분한 보호 수준을 제공한다.

참고: 요청의 다른 부분을 포괄하는 서명은 이 명세의 범위를 벗어나지만, 서명할 추가 정보를 DPoP 증명에 추가할 수 있다.

11.8. 액세스 토큰과 공개 키 바인딩

섹션 6에 명시된 액세스 토큰과 DPoP 공개 키의 바인딩은 공개 키의 JWK 표현에 대한 암호화 해시를 사용한다. 이는 동일한 해시 출력 값을 생성하는 다른 키를 찾거나 만드는 것이 계산상 불가능하도록 하기 위해 해시 함수가 충분한 제2원상 저항성을 갖는 것에 의존한다. SHA-256 해시 함수는 앞서 언급한 요구사항을 충족하면서 널리 사용할 수 있기 때문에 사용되었다.

마찬가지로, DPoP 증명과 액세스 토큰의 바인딩은 DPoP 증명의 ath 클레임 값으로 해당 액세스 토큰의 해시를 사용한다(섹션 4.2 참조). 이는 해시 값이 액세스 토큰을 신뢰성 있게 식별할 수 있을 만큼 충분히 고유하다는 것에 의존한다. SHA-256의 충돌 저항성은 그 요구사항을 충족한다.

11.9. 인가 코드와 공개 키 바인딩

인가 코드를 DPoP 공개 키에 암호학적으로 바인딩하는 것은 섹션 10에 명시되어 있다. 이 바인딩은 공격자가 인가 코드를 캡처하고, 클라이언트가 보유한 키가 아닌 다른 소유 증명 키를 사용해 DPoP 증명을 생성한 뒤, 그 DPoP 증명으로 인가 코드를 교환하는 공격을 방지한다. 클라이언트의 DPoP 키만 사용할 수 있음을 종단 간으로 보장함으로써, 캡처된 인가 코드가 유출되어 인가 코드가 발급된 위치 외의 곳에서 사용되는 것을 방지한다.

예를 들어, 인가 코드는 이를 포함한 HTTP 메시지가 기록되는 곳에서 공격자에 의해 수집될 수 있다. 인가 코드를 일회용으로 만들기 위한 노력이 이루어지더라도, 실제로는 공격자가 이를 재전송할 수 있는 시간 창이 존재하는 경우가 많다. 예를 들어, 인가 서버가 확장 가능한 복제 서비스로 구현된 경우, 일부 복제본은 재전송을 방지하는 데 필요한 정보를 아직 일시적으로 갖고 있지 않을 수 있다. 인가 코드의 DPoP 바인딩은 이러한 문제를 해결한다.

인가 서버가 인가 코드의 단일 사용 제한을 엄격하게 강제하지 않거나 강제할 수 없고, 공격자가 인가 코드(및 PKCE가 사용되는 경우 code_verifier)에 접근할 수 있다면, 공격자는 위조된 토큰 요청을 만들어 결과 토큰을 공격자가 제어하는 키에 바인딩할 수 있다. 예를 들어 XSS를 사용해 공격자는 인가 코드와 PKCE 매개변수에 대한 접근 권한을 얻을 수 있다. dpop_jkt 매개변수를 사용하면 이 공격을 방지할 수 있다.

인가 코드와 DPoP 공개 키의 바인딩은 액세스 토큰 바인딩과 마찬가지로 공개 키의 JWK Thumbprint를 사용한다. 동일한 JWK Thumbprint 고려사항이 적용된다.

11.10. 해시 알고리즘 민첩성

여기서 정의된 jkt 확인 방법 멤버, ath JWT 클레임, 및 dpop_jkt 인가 요청 매개변수는 모두 SHA-256 해시 함수의 출력을 그 값으로 사용한다. 이 명세가 단일 해시 함수를 사용하는 것은 의도적인 것이며, 매개변수화된 알고리즘 민첩성 스킴을 구현하고 배포할 때 흔히 발생하는 실수로 인한 잠재적인 보안 및 상호운용성 문제를 피하고 단순성을 확보하려는 목적이다. 그러나 미래의 상황이 변화하여 SHA-256이 이 명세의 요구사항에 충분하지 않게 되는 경우, 다른 해시 함수를 사용하는 것이 배제되지는 않는다. 그러한 필요가 생기면, 이 명세를 업데이트하는 짧은 명세가 작성될 것으로 기대된다. 적절한 해시 함수의 출력을 값으로 사용하여, 그 명세는 새로운 확인 방법 멤버, 새로운 JWT 클레임, 그리고 새로운 인가 요청 매개변수를 정의할 가능성이 높다. 이러한 항목은 이 명세가 정의한 더 큰 프로토콜의 동일한 메시지 구조와 흐름에서 각각의 대응 항목을 대신하거나 그와 함께 사용될 것이다.

11.11. 클라이언트 신원에 대한 바인딩

DPoP가 클라이언트 인증과 함께 사용되는 경우, 이는 동일한 TLS 터널 안에 우연히 함께 존재함으로써만 인증에 바인딩된다. DPoP 증명은 인증에 직접 암호학적으로 바인딩되어 있지 않으므로, 인증 또는 DPoP 메시지가 터널 안으로 복사되었을 가능성이 있다. DPoP에 URI를 포함하면 이러한 위험의 일부를 부분적으로 완화할 수 있지만, 인증과 DPoP 사이에 암호학적 바인딩을 제공하도록 인증 메커니즘을 수정하면 더 나은 보호를 제공할 수 있다. 그러나 인증 메커니즘의 수정이나 다른 수단을 통해 인증과의 추가 바인딩을 제공하는 것은 이 명세의 범위를 벗어난다.

12. IANA 고려사항

12.1. OAuth 액세스 토큰 유형 등록

IANA는 [RFC6749]에 의해 설정된 "OAuth Access Token Types" 레지스트리 [IANA.OAuth.Params]에 다음 액세스 토큰 유형을 등록했다.

이름:
DPoP
추가 토큰 엔드포인트 응답 매개변수:
(없음)
HTTP 인증 스킴:
DPoP
변경 관리자:
IETF
참조:
RFC 9449

12.2. OAuth 확장 오류 등록

IANA는 [RFC6749]에 의해 설정된 "OAuth Extensions Error" 레지스트리 [IANA.OAuth.Params]에 다음 오류 값을 등록했다.

유효하지 않은 DPoP 증명:


이름:
invalid_dpop_proof
사용 위치:
토큰 오류 응답, 리소스 접근 오류 응답
프로토콜 확장:
Demonstrating Proof of Possession(DPoP)
변경 관리자:
IETF
참조:
RFC 9449
DPoP nonce 사용:


이름:
use_dpop_nonce
사용 위치:
토큰 오류 응답, 리소스 접근 오류 응답
프로토콜 확장:
Demonstrating Proof of Possession(DPoP)
변경 관리자:
IETF
참조:
RFC 9449

12.3. OAuth 매개변수 등록

IANA는 [RFC6749]에 의해 설정된 "OAuth Parameters" 레지스트리 [IANA.OAuth.Params]에 다음 인가 요청 매개변수를 등록했다.

이름:
dpop_jkt
매개변수 사용 위치:
인가 요청
변경 관리자:
IETF
참조:
RFC 9449의 섹션 10

12.4. HTTP 인증 스킴 등록

IANA는 [RFC9110], 섹션 16.4.1에 의해 설정된 "HTTP Authentication Schemes" 레지스트리 [IANA.HTTP.AuthSchemes]에 다음 스킴을 등록했다.

인증 스킴 이름:
DPoP
참조:
RFC 9449의 섹션 7.1

12.5. 미디어 유형 등록

IANA는 [RFC6838]에 설명된 방식으로 "Media Types" 레지스트리 [IANA.MediaTypes]application/dpop+jwt 미디어 유형 [RFC2046]을 등록했으며, 이는 콘텐츠가 DPoP JWT임을 나타내는 데 사용된다.

유형 이름:
application
하위 유형 이름:
dpop+jwt
필수 매개변수:
n/a
선택적 매개변수:
n/a
인코딩 고려사항:
binary. DPoP JWT는 JWT이다. JWT 값은 마침표('.') 문자로 구분된 일련의 base64url 인코딩 값(그중 일부는 빈 문자열일 수 있음)으로 인코딩된다.
보안 고려사항:
RFC 9449의 섹션 11 참조
상호운용성 고려사항:
n/a
발행된 명세:
RFC 9449
이 미디어 유형을 사용하는 애플리케이션:
애플리케이션 수준 소유 증명을 위해 RFC 9449를 사용하는 애플리케이션
프래그먼트 식별자 고려사항:
n/a
추가 정보:


파일 확장자:
n/a
Macintosh 파일 유형 코드:
n/a
추가 정보를 위한 담당자 및 이메일 주소:
Michael B. Jones, michael_b_jones@hotmail.com
의도된 사용:
COMMON
사용 제한:
none
저자:
Michael B. Jones, michael_b_jones@hotmail.com
변경 관리자:
IETF

12.6. JWT 확인 방법 등록

IANA는 [RFC7800]에 의해 설정된 "JWT Confirmation Methods" 레지스트리 [IANA.JWT]에 다음 JWT cnf 멤버 값을 등록했다.

확인 방법 값:
jkt
확인 방법 설명:
JWK SHA-256 Thumbprint
변경 관리자:
IETF
참조:
RFC 9449의 섹션 6

12.7. JSON Web Token 클레임 등록

IANA는 [RFC7519]에 의해 설정된 "JSON Web Token Claims" 레지스트리 [IANA.JWT]에 다음 클레임을 등록했다.

HTTP 메서드:


클레임 이름:
htm
클레임 설명:
요청의 HTTP 메서드
변경 관리자:
IETF
참조:
RFC 9449의 섹션 4.2
HTTP URI:


클레임 이름:
htu
클레임 설명:
요청의 HTTP URI (쿼리 및 프래그먼트 부분 제외)
변경 관리자:
IETF
참조:
RFC 9449의 섹션 4.2
액세스 토큰 해시:


클레임 이름:
ath
클레임 설명:
관련 액세스 토큰 값의 ASCII 인코딩에 대한 base64url 인코딩된 SHA-256 해시
변경 관리자:
IETF
참조:
RFC 9449의 섹션 4.2

12.7.1. "nonce" 등록 업데이트

Internet Security Glossary [RFC4949]는 nonce에 대해, 프로토콜이 교환하는 데이터에 포함되는 임의 또는 반복되지 않는 값으로, 일반적으로 활성성을 보장하여 재전송 공격을 탐지하고 방어하기 위한 목적이라는 유용한 정의를 제공한다.

그러나 [OpenID.Core]에 의한 nonce 클레임의 최초 등록은 해당 애플리케이션에 문맥적으로 특정한 언어를 사용했으며, 이는 그 일반적인 적용 가능성을 잠재적으로 제한했다.

따라서 IANA는 이 클레임이 다른 컨텍스트와 JWT의 다른 적용에서도 적절히 사용될 수 있음을 반영하고, 이 문서를 참조로 추가하기 위해 "JSON Web Token Claims" 레지스트리 [IANA.JWT]nonce 항목을 다음과 같이 확장된 정의로 업데이트했다.

클레임 이름:
nonce
클레임 설명:
클라이언트 세션을 ID Token과 연결하는 데 사용되는 값(JWT의 다른 애플리케이션에서 nonce 값으로도 사용될 수 있음 MAY)
변경 관리자:
OpenID Foundation Artifact Binding Working Group, openid-specs-ab@lists.openid.net
명세 문서:
[OpenID.Core]의 섹션 2 및 RFC 9449

12.8. Hypertext Transfer Protocol(HTTP) 필드 이름 등록

IANA는 이 문서가 명시한 다음 HTTP 헤더 필드를, [RFC9110]에 의해 설정된 "Hypertext Transfer Protocol (HTTP) Field Name Registry" [IANA.HTTP.Fields]에 등록했다.

DPoP:


필드 이름:
DPoP
상태:
permanent
참조:
RFC 9449
DPoP-Nonce:


필드 이름:
DPoP-Nonce
상태:
permanent
참조:
RFC 9449

12.9. OAuth 인가 서버 메타데이터 등록

IANA는 [RFC8414]에 의해 설정된 "OAuth Authorization Server Metadata" 레지스트리 [IANA.OAuth.Params]에 다음 값을 등록했다.

메타데이터 이름:
dpop_signing_alg_values_supported
메타데이터 설명:
DPoP 증명 JWT에 대해 지원되는 JWS 알고리즘 목록을 포함하는 JSON 배열
변경 관리자:
IETF
참조:
RFC 9449의 섹션 5.1

12.10. OAuth 동적 클라이언트 등록 메타데이터

IANA는 [RFC7591]에 의해 설정된 IANA "OAuth Dynamic Client Registration Metadata" 레지스트리 [IANA.OAuth.Params]에 다음 값을 등록했다.

클라이언트 메타데이터 이름:
dpop_bound_access_tokens
클라이언트 메타데이터 설명:
클라이언트가 토큰 요청에 항상 DPoP를 사용하는지 여부를 지정하는 불리언 값
변경 관리자:
IETF
참조:
RFC 9449의 섹션 5.2

13. 참고 문헌

13.1. 규범적 참고 문헌

[RFC2119]
Bradner, S., "요구 수준을 나타내기 위해 RFC에서 사용하는 핵심 단어", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): 일반 구문", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC5234]
Crocker, D., Ed. and P. Overell, "구문 명세를 위한 Augmented BNF: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, , <https://www.rfc-editor.org/info/rfc5234>.
[RFC6125]
Saint-Andre, P. and J. Hodges, "Transport Layer Security(TLS) 컨텍스트에서 X.509(PKIX) 인증서를 사용하는 인터넷 공개 키 인프라 내 도메인 기반 애플리케이션 서비스 신원의 표현 및 검증", RFC 6125, DOI 10.17487/RFC6125, , <https://www.rfc-editor.org/info/rfc6125>.
[RFC6749]
Hardt, D., Ed., "OAuth 2.0 인가 프레임워크", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/info/rfc6749>.
[RFC6750]
Jones, M. and D. Hardt, "OAuth 2.0 인가 프레임워크: 베어러 토큰 사용", RFC 6750, DOI 10.17487/RFC6750, , <https://www.rfc-editor.org/info/rfc6750>.
[RFC7515]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature(JWS)", RFC 7515, DOI 10.17487/RFC7515, , <https://www.rfc-editor.org/info/rfc7515>.
[RFC7517]
Jones, M., "JSON Web Key(JWK)", RFC 7517, DOI 10.17487/RFC7517, , <https://www.rfc-editor.org/info/rfc7517>.
[RFC7519]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token(JWT)", RFC 7519, DOI 10.17487/RFC7519, , <https://www.rfc-editor.org/info/rfc7519>.
[RFC7638]
Jones, M. and N. Sakimura, "JSON Web Key(JWK) Thumbprint", RFC 7638, DOI 10.17487/RFC7638, , <https://www.rfc-editor.org/info/rfc7638>.
[RFC7800]
Jones, M., Bradley, J., and H. Tschofenig, "JSON Web Token(JWT)을 위한 소유 증명 키 의미론", RFC 7800, DOI 10.17487/RFC7800, , <https://www.rfc-editor.org/info/rfc7800>.
[RFC8174]
Leiba, B., "RFC 2119 핵심 단어에서 대문자와 소문자의 모호성", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[SHS]
National Institute of Standards and Technology, "Secure Hash Standard(SHS)", FIPS PUB 180-4, DOI 10.6028/NIST.FIPS.180-4, , <http://dx.doi.org/10.6028/NIST.FIPS.180-4>.

13.2. 정보성 참고 문헌

[BREACH]
CVE, "CVE-2013-3587", <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3587>.
[Cloudbleed]
Graham-Cumming, J., "Cloudflare 파서 버그로 인한 메모리 유출 사고 보고서", , <https://blog.cloudflare.com/incident-report-on-memory-leak-caused-by-cloudflare-parser-bug/>.
[CRIME]
CVE, "CVE-2012-4929", <https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2012-4929>.
[GitHub.Tokens]
Hanley, M., "보안 경고: 두 서드파티 통합자에게 발급된 도난 OAuth 사용자 토큰과 관련된 공격 캠페인", , <https://github.blog/2022-04-15-security-alert-stolen-oauth-user-tokens/>.
[Heartbleed]
"CVE-2014-0160", <https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2014-0160>.
[IANA.HTTP.AuthSchemes]
IANA, "Hypertext Transfer Protocol(HTTP) 인증 스킴 레지스트리", <https://www.iana.org/assignments/http-authschemes/>.
[IANA.HTTP.Fields]
IANA, "Hypertext Transfer Protocol(HTTP) 필드 이름 레지스트리", <https://www.iana.org/assignments/http-fields/>.
[IANA.JOSE.ALGS]
IANA, "JSON Web Signature and Encryption Algorithms", <https://www.iana.org/assignments/jose/>.
[IANA.JWT]
IANA, "JSON Web Token Claims", <https://www.iana.org/assignments/jwt/>.
[IANA.MediaTypes]
IANA, "Media Types", <https://www.iana.org/assignments/media-types/>.
[IANA.OAuth.Params]
IANA, "OAuth Parameters", <https://www.iana.org/assignments/oauth-parameters/>.
[OpenID.Core]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "정오표 세트 1을 포함한 OpenID Connect Core 1.0", , <https://openid.net/specs/openid-connect-core-1_0.html>.
[RFC2046]
Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions(MIME) Part Two: 미디어 유형", RFC 2046, DOI 10.17487/RFC2046, , <https://www.rfc-editor.org/info/rfc2046>.
[RFC4122]
Leach, P., Mealling, M., and R. Salz, "Universally Unique IDentifier(UUID) URN 네임스페이스", RFC 4122, DOI 10.17487/RFC4122, , <https://www.rfc-editor.org/info/rfc4122>.
[RFC4949]
Shirey, R., "인터넷 보안 용어집, 버전 2", FYI 36, RFC 4949, DOI 10.17487/RFC4949, , <https://www.rfc-editor.org/info/rfc4949>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, "미디어 유형 명세 및 등록 절차", BCP 13, RFC 6838, DOI 10.17487/RFC6838, , <https://www.rfc-editor.org/info/rfc6838>.
[RFC7523]
Jones, M., Campbell, B., and C. Mortimore, "OAuth 2.0 클라이언트 인증 및 인가 그랜트를 위한 JSON Web Token(JWT) 프로파일", RFC 7523, DOI 10.17487/RFC7523, , <https://www.rfc-editor.org/info/rfc7523>.
[RFC7591]
Richer, J., Ed., Jones, M., Bradley, J., Machulak, M., and P. Hunt, "OAuth 2.0 동적 클라이언트 등록 프로토콜", RFC 7591, DOI 10.17487/RFC7591, , <https://www.rfc-editor.org/info/rfc7591>.
[RFC7636]
Sakimura, N., Ed., Bradley, J., and N. Agarwal, "OAuth 공개 클라이언트를 위한 Proof Key for Code Exchange", RFC 7636, DOI 10.17487/RFC7636, , <https://www.rfc-editor.org/info/rfc7636>.
[RFC7662]
Richer, J., Ed., "OAuth 2.0 토큰 인트로스펙션", RFC 7662, DOI 10.17487/RFC7662, , <https://www.rfc-editor.org/info/rfc7662>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 인가 서버 메타데이터", RFC 8414, DOI 10.17487/RFC8414, , <https://www.rfc-editor.org/info/rfc8414>.
[RFC8705]
Campbell, B., Bradley, J., Sakimura, N., and T. Lodderstedt, "OAuth 2.0 Mutual-TLS 클라이언트 인증 및 인증서 바인딩 액세스 토큰", RFC 8705, DOI 10.17487/RFC8705, , <https://www.rfc-editor.org/info/rfc8705>.
[RFC8707]
Campbell, B., Bradley, J., and H. Tschofenig, "OAuth 2.0을 위한 리소스 지시자", RFC 8707, DOI 10.17487/RFC8707, , <https://www.rfc-editor.org/info/rfc8707>.
[RFC8725]
Sheffer, Y., Hardt, D., and M. Jones, "JSON Web Token 최선 현행 관행", BCP 225, RFC 8725, DOI 10.17487/RFC8725, , <https://www.rfc-editor.org/info/rfc8725>.
[RFC8792]
Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, "Internet-Drafts 및 RFC의 콘텐츠에서 긴 줄 처리", RFC 8792, DOI 10.17487/RFC8792, , <https://www.rfc-editor.org/info/rfc8792>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP 의미론", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[RFC9126]
Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D., and F. Skokan, "OAuth 2.0 푸시된 인가 요청", RFC 9126, DOI 10.17487/RFC9126, , <https://www.rfc-editor.org/info/rfc9126>.
[SECURITY-TOPICS]
Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, "OAuth 2.0 보안 최선 현행 관행", 진행 중인 작업, Internet-Draft, draft-ietf-oauth-security-topics-23, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-23>.
[TOKEN-BINDING]
Jones, M., Campbell, B., Bradley, J., and W. Denniss, "OAuth 2.0 토큰 바인딩", 진행 중인 작업, Internet-Draft, draft-ietf-oauth-token-binding-08, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-token-binding-08>.
[W3C.CSP]
West, M., "Content Security Policy Level 3", W3C Working Draft, , <https://www.w3.org/TR/CSP3/>.
[W3C.WebCryptoAPI]
Watson, M., "Web Cryptography API", W3C Recommendation, , <https://www.w3.org/TR/2017/REC-WebCryptoAPI-20170126>.
[WHATWG.Fetch]
WHATWG, "Fetch Living Standard", , <https://fetch.spec.whatwg.org/>.

감사의 말

우리는 Brock Allen, Annabelle Backman, Dominick Baier, Spencer Balogh, Vittorio Bertocci, Jeff Corrigan, Domingos Creado, Philippe De Ryck, Andrii Deinega, William Denniss, Vladimir Dzhuvinov, Mike Engan, Nikos Fotiou, Mark Haine, Dick Hardt, Joseph Heenan, Bjorn Hjelm, Jacob Ideskog, Jared Jennings, Benjamin Kaduk, Pieter Kasselman, Neil Madden, Rohan Mahy, Karsten Meyer zu Selhausen, Nicolas Mora, Steinar Noem, Mark Nottingham, Rob Otto, Aaron Parecki, Michael Peck, Roberto Polli, Paul Querna, Justin Richer, Joseph Salowey, Rifaat Shekh-Yusef, Filip Skokan, Dmitry Telegin, Dave Tonge, Jim Willeke, 그리고 이 작업에 대한 귀중한 의견, 피드백, 일반적인 지원을 제공한 다른 이들에게 감사한다.

이 문서는 독일 슈투트가르트에서 열린 제4회 OAuth Security Workshop의 논의에서 비롯되었다. 우리는 이 워크숍의 주최자 (Ralf KüstersGuido Schmitz)에게 감사한다.

저자 주소

Daniel Fett
Authlete
Brian Campbell
Ping Identity
John Bradley
Yubico
Torsten Lodderstedt
Tuconic
Michael Jones
Self-Issued Consulting
David Waite
Ping Identity