rfc9449.original | rfc9449.txt | |||
---|---|---|---|---|
Web Authorization Protocol D. Fett | Internet Engineering Task Force (IETF) D. Fett | |||
Internet-Draft Authlete | Request for Comments: 9449 Authlete | |||
Intended status: Standards Track B. Campbell | Category: Standards Track B. Campbell | |||
Expires: 15 October 2023 Ping Identity | ISSN: 2070-1721 Ping Identity | |||
J. Bradley | J. Bradley | |||
Yubico | Yubico | |||
T. Lodderstedt | T. Lodderstedt | |||
yes.com | Tuconic | |||
M. Jones | M. Jones | |||
independent | Self-Issued Consulting | |||
D. Waite | D. Waite | |||
Ping Identity | Ping Identity | |||
13 April 2023 | September 2023 | |||
OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer | OAuth 2.0 Demonstrating Proof of Possession (DPoP) | |||
(DPoP) | ||||
draft-ietf-oauth-dpop-16 | ||||
Abstract | Abstract | |||
This document describes a mechanism for sender-constraining OAuth 2.0 | This document describes a mechanism for sender-constraining OAuth 2.0 | |||
tokens via a proof-of-possession mechanism on the application level. | tokens via a proof-of-possession mechanism on the application level. | |||
This mechanism allows for the detection of replay attacks with access | This mechanism allows for the detection of replay attacks with access | |||
and refresh tokens. | and refresh tokens. | |||
Status of This Memo | Status of This Memo | |||
This Internet-Draft is submitted in full conformance with the | This is an Internet Standards Track document. | |||
provisions of BCP 78 and BCP 79. | ||||
Internet-Drafts are working documents of the Internet Engineering | ||||
Task Force (IETF). Note that other groups may also distribute | ||||
working documents as Internet-Drafts. The list of current Internet- | ||||
Drafts is at https://datatracker.ietf.org/drafts/current/. | ||||
Internet-Drafts are draft documents valid for a maximum of six months | This document is a product of the Internet Engineering Task Force | |||
and may be updated, replaced, or obsoleted by other documents at any | (IETF). It represents the consensus of the IETF community. It has | |||
time. It is inappropriate to use Internet-Drafts as reference | received public review and has been approved for publication by the | |||
material or to cite them other than as "work in progress." | Internet Engineering Steering Group (IESG). Further information on | |||
Internet Standards is available in Section 2 of RFC 7841. | ||||
This Internet-Draft will expire on 15 October 2023. | Information about the current status of this document, any errata, | |||
and how to provide feedback on it may be obtained at | ||||
https://www.rfc-editor.org/info/rfc9449. | ||||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2023 IETF Trust and the persons identified as the | Copyright (c) 2023 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents (https://trustee.ietf.org/ | Provisions Relating to IETF Documents | |||
license-info) in effect on the date of publication of this document. | (https://trustee.ietf.org/license-info) in effect on the date of | |||
Please review these documents carefully, as they describe your rights | publication of this document. Please review these documents | |||
and restrictions with respect to this document. Code Components | carefully, as they describe your rights and restrictions with respect | |||
extracted from this document must include Revised BSD License text as | to this document. Code Components extracted from this document must | |||
described in Section 4.e of the Trust Legal Provisions and are | include Revised BSD License text as described in Section 4.e of the | |||
provided without warranty as described in the Revised BSD License. | Trust Legal Provisions and are provided without warranty as described | |||
in the Revised BSD License. | ||||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction | |||
1.1. Conventions and Terminology . . . . . . . . . . . . . . . 4 | 1.1. Conventions and Terminology | |||
2. Objectives . . . . . . . . . . . . . . . . . . . . . . . . . 5 | 2. Objectives | |||
3. Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 | 3. Concept | |||
4. DPoP Proof JWTs . . . . . . . . . . . . . . . . . . . . . . . 8 | 4. DPoP Proof JWTs | |||
4.1. The DPoP HTTP Header . . . . . . . . . . . . . . . . . . 8 | 4.1. The DPoP HTTP Header | |||
4.2. DPoP Proof JWT Syntax . . . . . . . . . . . . . . . . . . 9 | 4.2. DPoP Proof JWT Syntax | |||
4.3. Checking DPoP Proofs . . . . . . . . . . . . . . . . . . 11 | 4.3. Checking DPoP Proofs | |||
5. DPoP Access Token Request . . . . . . . . . . . . . . . . . . 12 | 5. DPoP Access Token Request | |||
5.1. Authorization Server Metadata . . . . . . . . . . . . . . 15 | 5.1. Authorization Server Metadata | |||
5.2. Client Registration Metadata . . . . . . . . . . . . . . 15 | 5.2. Client Registration Metadata | |||
6. Public Key Confirmation . . . . . . . . . . . . . . . . . . . 16 | 6. Public Key Confirmation | |||
6.1. JWK Thumbprint Confirmation Method . . . . . . . . . . . 16 | 6.1. JWK Thumbprint Confirmation Method | |||
6.2. JWK Thumbprint Confirmation Method in Token | 6.2. JWK Thumbprint Confirmation Method in Token Introspection | |||
Introspection . . . . . . . . . . . . . . . . . . . . . . 17 | 7. Protected Resource Access | |||
7. Protected Resource Access . . . . . . . . . . . . . . . . . . 18 | 7.1. The DPoP Authentication Scheme | |||
7.1. The DPoP Authentication Scheme . . . . . . . . . . . . . 19 | 7.2. Compatibility with the Bearer Authentication Scheme | |||
7.2. Compatibility with the Bearer Authentication Scheme . . . 22 | 7.3. Client Considerations | |||
7.3. Client Considerations . . . . . . . . . . . . . . . . . . 24 | 8. Authorization Server-Provided Nonce | |||
8. Authorization Server-Provided Nonce . . . . . . . . . . . . . 24 | 8.1. Nonce Syntax | |||
8.1. Nonce Syntax . . . . . . . . . . . . . . . . . . . . . . 26 | 8.2. Providing a New Nonce Value | |||
8.2. Providing a New Nonce Value . . . . . . . . . . . . . . . 26 | 9. Resource Server-Provided Nonce | |||
9. Resource Server-Provided Nonce . . . . . . . . . . . . . . . 27 | 10. Authorization Code Binding to a DPoP Key | |||
10. Authorization Code Binding to DPoP Key . . . . . . . . . . . 28 | 10.1. DPoP with Pushed Authorization Requests | |||
10.1. DPoP with Pushed Authorization Requests . . . . . . . . 28 | 11. Security Considerations | |||
11. Security Considerations . . . . . . . . . . . . . . . . . . . 29 | 11.1. DPoP Proof Replay | |||
11.1. DPoP Proof Replay . . . . . . . . . . . . . . . . . . . 29 | 11.2. DPoP Proof Pre-generation | |||
11.2. DPoP Proof Pre-Generation . . . . . . . . . . . . . . . 30 | 11.3. DPoP Nonce Downgrade | |||
11.3. DPoP Nonce Downgrade . . . . . . . . . . . . . . . . . . 31 | 11.4. Untrusted Code in the Client Context | |||
11.4. Untrusted Code in the Client Context . . . . . . . . . . 31 | 11.5. Signed JWT Swapping | |||
11.5. Signed JWT Swapping . . . . . . . . . . . . . . . . . . 32 | 11.6. Signature Algorithms | |||
11.6. Signature Algorithms . . . . . . . . . . . . . . . . . . 32 | 11.7. Request Integrity | |||
11.7. Request Integrity . . . . . . . . . . . . . . . . . . . 32 | 11.8. Access Token and Public Key Binding | |||
11.8. Access Token and Public Key Binding . . . . . . . . . . 33 | 11.9. Authorization Code and Public Key Binding | |||
11.9. Authorization Code and Public Key Binding . . . . . . . 33 | 11.10. Hash Algorithm Agility | |||
11.10. Hash Algorithm Agility . . . . . . . . . . . . . . . . . 34 | 11.11. Binding to Client Identity | |||
11.11. Binding to Client Identity . . . . . . . . . . . . . . . 34 | 12. IANA Considerations | |||
12.1. OAuth Access Token Types Registration | ||||
12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 34 | 12.2. OAuth Extensions Error Registration | |||
12.1. OAuth Access Token Type Registration . . . . . . . . . . 34 | 12.3. OAuth Parameters Registration | |||
12.2. OAuth Extensions Error Registration . . . . . . . . . . 35 | 12.4. HTTP Authentication Schemes Registration | |||
12.3. OAuth Parameters Registration . . . . . . . . . . . . . 35 | 12.5. Media Type Registration | |||
12.4. HTTP Authentication Scheme Registration . . . . . . . . 35 | 12.6. JWT Confirmation Methods Registration | |||
12.5. Media Type Registration . . . . . . . . . . . . . . . . 36 | 12.7. JSON Web Token Claims Registration | |||
12.6. JWT Confirmation Methods Registration . . . . . . . . . 36 | 12.7.1. "nonce" Registration Update | |||
12.7. JSON Web Token Claims Registration . . . . . . . . . . . 36 | 12.8. Hypertext Transfer Protocol (HTTP) Field Name Registration | |||
12.7.1. "nonce" Registry Update . . . . . . . . . . . . . . 37 | 12.9. OAuth Authorization Server Metadata Registration | |||
12.8. HTTP Message Header Field Names Registration . . . . . . 38 | 12.10. OAuth Dynamic Client Registration Metadata | |||
12.9. OAuth Authorization Server Metadata Registration . . . . 38 | 13. References | |||
12.10. OAuth Dynamic Client Registration Metadata . . . . . . . 38 | 13.1. Normative References | |||
13. Normative References . . . . . . . . . . . . . . . . . . . . 38 | 13.2. Informative References | |||
14. Informative References . . . . . . . . . . . . . . . . . . . 40 | Acknowledgements | |||
Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 43 | Authors' Addresses | |||
Appendix B. Document History . . . . . . . . . . . . . . . . . . 44 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 48 | ||||
1. Introduction | 1. Introduction | |||
DPoP (for Demonstrating Proof-of-Possession at the Application Layer) | Demonstrating Proof of Possession (DPoP) is an application-level | |||
is an application-level mechanism for sender-constraining OAuth | mechanism for sender-constraining OAuth [RFC6749] access and refresh | |||
[RFC6749] access and refresh tokens. It enables a client to prove | tokens. It enables a client to prove the possession of a public/ | |||
the possession of a public/private key pair by including a DPoP | private key pair by including a DPoP header in an HTTP request. The | |||
header in an HTTP request. The value of the header is a JSON Web | value of the header is a JSON Web Token (JWT) [RFC7519] that enables | |||
Token (JWT) [RFC7519] that enables the authorization server to bind | the authorization server to bind issued tokens to the public part of | |||
issued tokens to the public part of a client's key pair. Recipients | a client's key pair. Recipients of such tokens are then able to | |||
of such tokens are then able to verify the binding of the token to | verify the binding of the token to the key pair that the client has | |||
the key pair that the client has demonstrated that it holds via the | demonstrated that it holds via the DPoP header, thereby providing | |||
DPoP header, thereby providing some assurance that the client | some assurance that the client presenting the token also possesses | |||
presenting the token also possesses the private key. In other words, | the private key. In other words, the legitimate presenter of the | |||
the legitimate presenter of the token is constrained to be the sender | token is constrained to be the sender that holds and proves | |||
that holds and can prove possession of the private part of the key | possession of the private part of the key pair. | |||
pair. | ||||
The mechanism specified herein can be used in cases where other | The mechanism specified herein can be used in cases where other | |||
methods of sender-constraining tokens that utilize elements of the | methods of sender-constraining tokens that utilize elements of the | |||
underlying secure transport layer, such as [RFC8705] or | underlying secure transport layer, such as [RFC8705] or | |||
[I-D.ietf-oauth-token-binding], are not available or desirable. For | [TOKEN-BINDING], are not available or desirable. For example, due to | |||
example, due to a sub-par user experience of TLS client | a sub-par user experience of TLS client authentication in user agents | |||
authentication in user agents and a lack of support for HTTP token | and a lack of support for HTTP token binding, neither mechanism can | |||
binding, neither mechanism can be used if an OAuth client is an | be used if an OAuth client is an application that is dynamically | |||
application that is dynamically downloaded and executed in a web | downloaded and executed in a web browser (sometimes referred to as a | |||
browser (sometimes referred to as a "single-page application"). | "single-page application"). Additionally, applications that are | |||
Applications installed and run directly on a user's device are | installed and run directly on a user's device are well positioned to | |||
another example well positioned to benefit from DPoP-bound tokens to | benefit from DPoP-bound tokens that guard against the misuse of | |||
guard against misuse of tokens by a compromised or malicious | tokens by a compromised or malicious resource. Such applications | |||
resource. Such applications often have dedicated protected storage | often have dedicated protected storage for cryptographic keys. | |||
for cryptographic keys. | ||||
DPoP can be used to sender-constrain access tokens regardless of the | DPoP can be used to sender-constrain access tokens regardless of the | |||
client authentication method employed, but DPoP itself is not used | client authentication method employed, but DPoP itself is not used | |||
for client authentication. DPoP can also be used to sender-constrain | for client authentication. DPoP can also be used to sender-constrain | |||
refresh tokens issued to public clients (those without authentication | refresh tokens issued to public clients (those without authentication | |||
credentials associated with the client_id). | credentials associated with the client_id). | |||
1.1. Conventions and Terminology | 1.1. Conventions and Terminology | |||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
"OPTIONAL" in this document are to be interpreted as described in BCP | "OPTIONAL" in this document are to be interpreted as described in | |||
14 [RFC2119] [RFC8174] when, and only when, they appear in all | BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
capitals, as shown here. | capitals, as shown here. | |||
This specification uses the Augmented Backus-Naur Form (ABNF) | This specification uses the Augmented Backus-Naur Form (ABNF) | |||
notation of [RFC5234]. | notation of [RFC5234]. | |||
This specification uses the terms "access token", "refresh token", | This specification uses the terms "access token", "refresh token", | |||
"authorization server", "resource server", "authorization endpoint", | "authorization server", "resource server", "authorization endpoint", | |||
"authorization request", "authorization response", "token endpoint", | "authorization request", "authorization response", "token endpoint", | |||
"grant type", "access token request", "access token response", | "grant type", "access token request", "access token response", | |||
"client", "public client", and "confidential client" defined by The | "client", "public client", and "confidential client" defined by "The | |||
OAuth 2.0 Authorization Framework [RFC6749]. | OAuth 2.0 Authorization Framework" [RFC6749]. | |||
The terms "request", "response", "header field", and "target URI" are | The terms "request", "response", "header field", and "target URI" are | |||
imported from [RFC9110]. | imported from [RFC9110]. | |||
The terms "JOSE" and "JOSE header" are imported from [RFC7515]. | The terms "JOSE" and "JOSE Header" are imported from [RFC7515]. | |||
This document contains non-normative examples of partial and complete | This document contains non-normative examples of partial and complete | |||
HTTP messages. Some examples use a single trailing backslash to | HTTP messages. Some examples use a single trailing backslash to | |||
indicate line wrapping for long values, as per [RFC8792]. The | indicate line wrapping for long values, as per [RFC8792]. The | |||
character and leading spaces on wrapped lines are not part of the | character and leading spaces on wrapped lines are not part of the | |||
value. | value. | |||
2. Objectives | 2. Objectives | |||
The primary aim of DPoP is to prevent unauthorized or illegitimate | The primary aim of DPoP is to prevent unauthorized or illegitimate | |||
skipping to change at page 5, line 27 ¶ | skipping to change at line 191 ¶ | |||
This constrains the legitimate sender of the token to only the party | This constrains the legitimate sender of the token to only the party | |||
with access to the private key and gives the server receiving the | with access to the private key and gives the server receiving the | |||
token added assurances that the sender is legitimately authorized to | token added assurances that the sender is legitimately authorized to | |||
use it. | use it. | |||
Access tokens that are sender-constrained via DPoP thus stand in | Access tokens that are sender-constrained via DPoP thus stand in | |||
contrast to the typical bearer token, which can be used by any party | contrast to the typical bearer token, which can be used by any party | |||
in possession of such a token. Although protections generally exist | in possession of such a token. Although protections generally exist | |||
to prevent unintended disclosure of bearer tokens, unforeseen vectors | to prevent unintended disclosure of bearer tokens, unforeseen vectors | |||
for leakage have occurred due to vulnerabilities and implementation | for leakage have occurred due to vulnerabilities and implementation | |||
issues in other layers in the protocol or software stack (CRIME | issues in other layers in the protocol or software stack (see, e.g., | |||
[CRIME], BREACH [BREACH], Heartbleed [Heartbleed], and the Cloudflare | Compression Ratio Info-leak Made Easy (CRIME) [CRIME], Browser | |||
parser bug [Cloudbleed] are some examples). There have also been | Reconnaissance and Exfiltration via Adaptive Compression of Hypertext | |||
numerous published token theft attacks on OAuth implementations | (BREACH) [BREACH], Heartbleed [Heartbleed], and the Cloudflare parser | |||
themselves ([GitHub.Tokens] as just one high profile example). DPoP | bug [Cloudbleed]). There have also been numerous published token | |||
provides a general defense in depth against the impact of | theft attacks on OAuth implementations themselves ([GitHub.Tokens] is | |||
unanticipated token leakage. DPoP is not, however, a substitute for | just one high-profile example). DPoP provides a general defense in | |||
a secure transport and MUST always be used in conjunction with HTTPS. | depth against the impact of unanticipated token leakage. DPoP is | |||
not, however, a substitute for a secure transport and MUST always be | ||||
used in conjunction with HTTPS. | ||||
The very nature of the typical OAuth protocol interaction | The very nature of the typical OAuth protocol interaction | |||
necessitates that the client discloses the access token to the | necessitates that the client discloses the access token to the | |||
protected resources that it accesses. The attacker model in | protected resources that it accesses. The attacker model in | |||
[I-D.ietf-oauth-security-topics] describes cases where a protected | [SECURITY-TOPICS] describes cases where a protected resource might be | |||
resource might be counterfeit, malicious or compromised and plays | counterfeit, malicious, or compromised and plays received tokens | |||
received tokens against other protected resources to gain | against other protected resources to gain unauthorized access. | |||
unauthorized access. Audience restricted access tokens (e.g., using | Audience-restricted access tokens (e.g., using the JWT [RFC7519] aud | |||
the JWT [RFC7519] aud claim) can prevent such misuse, however, doing | claim) can prevent such misuse. However, doing so in practice has | |||
so in practice has proven to be prohibitively cumbersome for many | proven to be prohibitively cumbersome for many deployments (despite | |||
deployments (even despite extensions such as [RFC8707]). Sender- | extensions such as [RFC8707]). Sender-constraining access tokens is | |||
constraining access tokens is a more robust and straightforward | a more robust and straightforward mechanism to prevent such token | |||
mechanism to prevent such token replay at a different endpoint and | replay at a different endpoint, and DPoP is an accessible | |||
DPoP is an accessible application layer means of doing so. | application-layer means of doing so. | |||
Due to the potential for cross-site scripting (XSS), browser-based | Due to the potential for cross-site scripting (XSS), browser-based | |||
OAuth clients bring to bear added considerations with respect to | OAuth clients bring to bear added considerations with respect to | |||
protecting tokens. The most straightforward XSS-based attack is for | protecting tokens. The most straightforward XSS-based attack is for | |||
an attacker to exfiltrate a token and use it themselves completely | an attacker to exfiltrate a token and use it themselves completely | |||
independent of the legitimate client. A stolen access token is used | independent of the legitimate client. A stolen access token is used | |||
for protected resource access and a stolen refresh token for | for protected resource access, and a stolen refresh token is used for | |||
obtaining new access tokens. If the private key is non-extractable | obtaining new access tokens. If the private key is non-extractable | |||
(as is possible with [W3C.WebCryptoAPI]), DPoP renders exfiltrated | (as is possible with [W3C.WebCryptoAPI]), DPoP renders exfiltrated | |||
tokens alone unusable. | tokens alone unusable. | |||
XSS vulnerabilities also allow an attacker to execute code in the | XSS vulnerabilities also allow an attacker to execute code in the | |||
context of the browser-based client application and maliciously use a | context of the browser-based client application and maliciously use a | |||
token indirectly through the client. That execution context has | token indirectly through the client. That execution context has | |||
access to utilize the signing key and thus can produce DPoP proofs to | access to utilize the signing key; thus, it can produce DPoP proofs | |||
use in conjunction with the token. At this application layer there | to use in conjunction with the token. At this application layer, | |||
is most likely no feasible defense against this threat except | there is most likely no feasible defense against this threat except | |||
generally preventing XSS, therefore it is considered out of scope for | generally preventing XSS; therefore, it is considered out of scope | |||
DPoP. | for DPoP. | |||
Malicious XSS code executed in the context of the browser-based | Malicious XSS code executed in the context of the browser-based | |||
client application is also in a position to create DPoP proofs with | client application is also in a position to create DPoP proofs with | |||
timestamp values in the future and exfiltrate them in conjunction | timestamp values in the future and exfiltrate them in conjunction | |||
with a token. These stolen artifacts can later be used independent | with a token. These stolen artifacts can later be used independent | |||
of the client application to access protected resources. To prevent | of the client application to access protected resources. To prevent | |||
this, servers can optionally require clients to include a server- | this, servers can optionally require clients to include a server- | |||
chosen value into the proof that cannot be predicted by an attacker | chosen value into the proof that cannot be predicted by an attacker | |||
(nonce). In the absence of the optional nonce, the impact of pre- | (nonce). In the absence of the optional nonce, the impact of pre- | |||
computed DPoP proofs is limited somewhat by the proof being bound to | computed DPoP proofs is limited somewhat by the proof being bound to | |||
an access token on protected resource access. Because a proof | an access token on protected resource access. Because a proof | |||
covering an access token that does not yet exist cannot feasibly be | covering an access token that does not yet exist cannot feasibly be | |||
created, access tokens obtained with an exfiltrated refresh token and | created, access tokens obtained with an exfiltrated refresh token and | |||
pre-computed proofs will be unusable. | pre-computed proofs will be unusable. | |||
Additional security considerations are discussed in Section 11. | Additional security considerations are discussed in Section 11. | |||
3. Concept | 3. Concept | |||
The main data structure introduced by this specification is a DPoP | The main data structure introduced by this specification is a DPoP | |||
proof JWT, described in detail below, which is sent as a header in an | proof JWT that is sent as a header in an HTTP request, as described | |||
HTTP request. A client uses a DPoP proof JWT to prove the possession | in detail below. A client uses a DPoP proof JWT to prove the | |||
of a private key corresponding to a certain public key. | possession of a private key corresponding to a certain public key. | |||
Roughly speaking, a DPoP proof is a signature over some data of the | Roughly speaking, a DPoP proof is a signature over: | |||
HTTP request to which it is attached, a timestamp, a unique | ||||
identifier, an optional server-provided nonce, and a hash of the | * some data of the HTTP request to which it is attached, | |||
associated access token when an access token is present within the | ||||
request. | * a timestamp, | |||
* a unique identifier, | ||||
* an optional server-provided nonce, and | ||||
* a hash of the associated access token when an access token is | ||||
present within the request. | ||||
+--------+ +---------------+ | +--------+ +---------------+ | |||
| |--(A)-- Token Request ------------------->| | | | |--(A)-- Token Request ------------------->| | | |||
| Client | (DPoP Proof) | Authorization | | | Client | (DPoP Proof) | Authorization | | |||
| | | Server | | | | | Server | | |||
| |<-(B)-- DPoP-bound Access Token ----------| | | | |<-(B)-- DPoP-Bound Access Token ----------| | | |||
| | (token_type=DPoP) +---------------+ | | | (token_type=DPoP) +---------------+ | |||
| | | | | | |||
| | | | | | |||
| | +---------------+ | | | +---------------+ | |||
| |--(C)-- DPoP-bound Access Token --------->| | | | |--(C)-- DPoP-Bound Access Token --------->| | | |||
| | (DPoP Proof) | Resource | | | | (DPoP Proof) | Resource | | |||
| | | Server | | | | | Server | | |||
| |<-(D)-- Protected Resource ---------------| | | | |<-(D)-- Protected Resource ---------------| | | |||
| | +---------------+ | | | +---------------+ | |||
+--------+ | +--------+ | |||
Figure 1: Basic DPoP Flow | Figure 1: Basic DPoP Flow | |||
The basic steps of an OAuth flow with DPoP (without the optional | The basic steps of an OAuth flow with DPoP (without the optional | |||
nonce) are shown in Figure 1: | nonce) are shown in Figure 1. | |||
* (A) In the Token Request, the client sends an authorization grant | A. In the token request, the client sends an authorization grant | |||
(e.g., an authorization code, refresh token, etc.) | (e.g., an authorization code, refresh token, etc.) to the | |||
to the authorization server in order to obtain an access token | authorization server in order to obtain an access token (and | |||
(and potentially a refresh token). The client attaches a DPoP | potentially a refresh token). The client attaches a DPoP proof | |||
proof to the request in an HTTP header. | to the request in an HTTP header. | |||
* (B) The authorization server binds (sender-constrains) the access | ||||
token to the public key claimed by the client in the DPoP proof; | B. The authorization server binds (sender-constrains) the access | |||
that is, the access token cannot be used without proving | token to the public key claimed by the client in the DPoP proof; | |||
possession of the respective private key. If a refresh token is | that is, the access token cannot be used without proving | |||
issued to a public client, it too is bound to the public key of | possession of the respective private key. If a refresh token is | |||
the DPoP proof. | issued to a public client, it is also bound to the public key of | |||
* (C) To use the access token, the client has to prove possession of | the DPoP proof. | |||
the private key by, again, adding a header to the request that | ||||
carries a DPoP proof for that request. The resource server needs | C. To use the access token, the client has to prove possession of | |||
to receive information about the public key to which the access | the private key by, again, adding a header to the request that | |||
token is bound. This information may be encoded directly into the | carries a DPoP proof for that request. The resource server needs | |||
access token (for JWT structured access tokens) or provided via | to receive information about the public key to which the access | |||
token introspection endpoint (not shown). The resource server | token is bound. This information may be encoded directly into | |||
verifies that the public key to which the access token is bound | the access token (for JWT-structured access tokens) or provided | |||
matches the public key of the DPoP proof. It also verifies that | via token introspection endpoint (not shown). The resource | |||
the access token hash in the DPoP proof matches the access token | server verifies that the public key to which the access token is | |||
presented in the request. | bound matches the public key of the DPoP proof. It also verifies | |||
* (D) The resource server refuses to serve the request if the | that the access token hash in the DPoP proof matches the access | |||
signature check fails or the data in the DPoP proof is wrong, | token presented in the request. | |||
e.g., the target URI does not match the URI claim in the DPoP | ||||
proof JWT. The access token itself, of course, must also be valid | D. The resource server refuses to serve the request if the signature | |||
in all other respects. | check fails or if the data in the DPoP proof is wrong, e.g., the | |||
target URI does not match the URI claim in the DPoP proof JWT. | ||||
The access token itself, of course, must also be valid in all | ||||
other respects. | ||||
The DPoP mechanism presented herein is not a client authentication | The DPoP mechanism presented herein is not a client authentication | |||
method. In fact, a primary use case of DPoP is for public clients | method. In fact, a primary use case of DPoP is for public clients | |||
(e.g., single page applications and applications on a user's device) | (e.g., single-page applications and applications on a user's device) | |||
that do not use client authentication. Nonetheless, DPoP is designed | that do not use client authentication. Nonetheless, DPoP is designed | |||
such that it is compatible with private_key_jwt and all other client | to be compatible with private_key_jwt and all other client | |||
authentication methods. | authentication methods. | |||
DPoP does not directly ensure message integrity but relies on the TLS | DPoP does not directly ensure message integrity, but it relies on the | |||
layer for that purpose. See Section 11 for details. | TLS layer for that purpose. See Section 11 for details. | |||
4. DPoP Proof JWTs | 4. DPoP Proof JWTs | |||
DPoP introduces the concept of a DPoP proof, which is a JWT created | DPoP introduces the concept of a DPoP proof, which is a JWT created | |||
by the client and sent with an HTTP request using the DPoP header | by the client and sent with an HTTP request using the DPoP header | |||
field. Each HTTP request requires a unique DPoP proof. | field. Each HTTP request requires a unique DPoP proof. | |||
A valid DPoP proof demonstrates to the server that the client holds | A valid DPoP proof demonstrates to the server that the client holds | |||
the private key that was used to sign the DPoP proof JWT. This | the private key that was used to sign the DPoP proof JWT. This | |||
enables authorization servers to bind issued tokens to the | enables authorization servers to bind issued tokens to the | |||
corresponding public key (as described in Section 5) and for resource | corresponding public key (as described in Section 5) and enables | |||
servers to verify the key-binding of tokens that it receives (see | resource servers to verify the key-binding of tokens that it receives | |||
Section 7.1), which prevents said tokens from being used by any | (see Section 7.1), which prevents said tokens from being used by any | |||
entity that does not have access to the private key. | entity that does not have access to the private key. | |||
The DPoP proof demonstrates possession of a key and, by itself, is | The DPoP proof demonstrates possession of a key and, by itself, is | |||
not an authentication or access control mechanism. When presented in | not an authentication or access control mechanism. When presented in | |||
conjunction with a key-bound access token as described in | conjunction with a key-bound access token as described in | |||
Section 7.1, the DPoP proof provides additional assurance about the | Section 7.1, the DPoP proof provides additional assurance about the | |||
legitimacy of the client to present the access token. However, a | legitimacy of the client to present the access token. However, a | |||
valid DPoP proof JWT is not sufficient alone to make access control | valid DPoP proof JWT is not sufficient alone to make access control | |||
decisions. | decisions. | |||
4.1. The DPoP HTTP Header | 4.1. The DPoP HTTP Header | |||
A DPoP proof is included in an HTTP request using the following | A DPoP proof is included in an HTTP request using the following | |||
request header field. | request header field. | |||
DPoP A JWT that adheres to the structure and syntax of Section 4.2. | DPoP: A JWT that adheres to the structure and syntax of Section 4.2. | |||
Figure 2 shows an example DPoP HTTP header field (with '\' line | Figure 2 shows an example DPoP HTTP header field. The example uses | |||
wrapping per RFC 8792). | "\" line wrapping per [RFC8792]. | |||
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ | DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ | |||
VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ | VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ | |||
nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ | nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ | |||
QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\ | QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\ | |||
oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\ | oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\ | |||
WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\ | WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\ | |||
4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg | 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg | |||
Figure 2: Example DPoP header | Figure 2: Example DPoP Header | |||
Note that per [RFC9110] header field names are case-insensitive; so | Note that per [RFC9110], header field names are case insensitive; | |||
DPoP, DPOP, dpop, etc., are all valid and equivalent header field | thus, DPoP, DPOP, dpop, etc., are all valid and equivalent header | |||
names. Case is significant in the header field value, however. | field names. However, case is significant in the header field value. | |||
The DPoP HTTP header field value uses the token68 syntax defined in | The DPoP HTTP header field value uses the token68 syntax defined in | |||
Section 11.2 of [RFC9110] (repeated below in Figure 3 for ease of | Section 11.2 of [RFC9110] and is repeated below in Figure 3 for ease | |||
reference). | of reference. | |||
DPoP = token68 | DPoP = token68 | |||
token68 = 1*( ALPHA / DIGIT / | token68 = 1*( ALPHA / DIGIT / | |||
"-" / "." / "_" / "~" / "+" / "/" ) *"=" | "-" / "." / "_" / "~" / "+" / "/" ) *"=" | |||
Figure 3: DPoP header field ABNF | Figure 3: DPoP Header Field ABNF | |||
4.2. DPoP Proof JWT Syntax | 4.2. DPoP Proof JWT Syntax | |||
A DPoP proof is a JWT ([RFC7519]) that is signed (using JSON Web | A DPoP proof is a JWT [RFC7519] that is signed (using JSON Web | |||
Signature (JWS) [RFC7515]) with a private key chosen by the client | Signature (JWS) [RFC7515]) with a private key chosen by the client | |||
(see below). The JOSE header of a DPoP JWT MUST contain at least the | (see below). The JOSE Header of a DPoP JWT MUST contain at least the | |||
following parameters: | following parameters: | |||
* typ: with value dpop+jwt, which explicitly types the DPoP proof | typ: A field with the value dpop+jwt, which explicitly types the | |||
JWT as recommended in Section 3.11 of [RFC8725]. | DPoP proof JWT as recommended in Section 3.11 of [RFC8725]. | |||
* alg: an identifier for a JWS asymmetric digital signature | ||||
algorithm from [IANA.JOSE.ALGS]. MUST NOT be none or an | alg: An identifier for a JWS asymmetric digital signature algorithm | |||
identifier for a symmetric algorithm (MAC). | from [IANA.JOSE.ALGS]. It MUST NOT be none or an identifier for a | |||
* jwk: representing the public key chosen by the client, in JSON Web | symmetric algorithm (Message Authentication Code (MAC)). | |||
Key (JWK) [RFC7517] format, as defined in Section 4.1.3 of | ||||
[RFC7515]. MUST NOT contain a private key. | jwk: Represents the public key chosen by the client in JSON Web Key | |||
(JWK) [RFC7517] format as defined in Section 4.1.3 of [RFC7515]. | ||||
It MUST NOT contain a private key. | ||||
The payload of a DPoP proof MUST contain at least the following | The payload of a DPoP proof MUST contain at least the following | |||
claims: | claims: | |||
* jti: Unique identifier for the DPoP proof JWT. The value MUST be | jti: Unique identifier for the DPoP proof JWT. The value MUST be | |||
assigned such that there is a negligible probability that the same | assigned such that there is a negligible probability that the same | |||
value will be assigned to any other DPoP proof used in the same | value will be assigned to any other DPoP proof used in the same | |||
context during the time window of validity. Such uniqueness can | context during the time window of validity. Such uniqueness can | |||
be accomplished by encoding (base64url or any other suitable | be accomplished by encoding (base64url or any other suitable | |||
encoding) at least 96 bits of pseudorandom data or by using a | encoding) at least 96 bits of pseudorandom data or by using a | |||
version 4 UUID string according to [RFC4122]. The jti can be used | version 4 Universally Unique Identifier (UUID) string according to | |||
by the server for replay detection and prevention, see | [RFC4122]. The jti can be used by the server for replay detection | |||
Section 11.1. | and prevention; see Section 11.1. | |||
* htm: The value of the HTTP method (Section 9.1 of [RFC9110]) of | ||||
the request to which the JWT is attached. | htm: The value of the HTTP method (Section 9.1 of [RFC9110]) of the | |||
* htu: The HTTP target URI (Section 7.1 of [RFC9110]), without query | request to which the JWT is attached. | |||
and fragment parts, of the request to which the JWT is attached. | ||||
* iat: Creation timestamp of the JWT ([RFC7519], section 4.1.6]). | htu: The HTTP target URI (Section 7.1 of [RFC9110]) of the request | |||
to which the JWT is attached, without query and fragment parts. | ||||
iat: Creation timestamp of the JWT (Section 4.1.6 of [RFC7519]). | ||||
When the DPoP proof is used in conjunction with the presentation of | When the DPoP proof is used in conjunction with the presentation of | |||
an access token in protected resource access, see Section 7, the DPoP | an access token in protected resource access (see Section 7), the | |||
proof MUST also contain the following claim: | DPoP proof MUST also contain the following claim: | |||
* ath: hash of the access token. The value MUST be the result of a | ath: Hash of the access token. The value MUST be the result of a | |||
base64url encoding (as defined in Section 2 of [RFC7515]) the | base64url encoding (as defined in Section 2 of [RFC7515]) the | |||
SHA-256 [SHS] hash of the ASCII encoding of the associated access | SHA-256 [SHS] hash of the ASCII encoding of the associated access | |||
token's value. | token's value. | |||
When the authentication server or resource server provides a DPoP- | When the authentication server or resource server provides a DPoP- | |||
Nonce HTTP header in a response (see Section 8, Section 9), the DPoP | Nonce HTTP header in a response (see Sections 8 and 9), the DPoP | |||
proof MUST also contain the following claim: | proof MUST also contain the following claim: | |||
* nonce: A recent nonce provided via the DPoP-Nonce HTTP header. | nonce: A recent nonce provided via the DPoP-Nonce HTTP header. | |||
A DPoP proof MAY contain other JOSE header parameters or claims as | A DPoP proof MAY contain other JOSE Header Parameters or claims as | |||
defined by extension, profile, or deployment specific requirements. | defined by extension, profile, or deployment-specific requirements. | |||
Figure 4 is a conceptual example showing the decoded content of the | Figure 4 is a conceptual example showing the decoded content of the | |||
DPoP proof in Figure 2. The JSON of the JWT header and payload are | DPoP proof in Figure 2. The JSON of the JWT header and payload are | |||
shown, but the signature part is omitted. As usual, line breaks and | shown, but the signature part is omitted. As usual, line breaks and | |||
extra spaces are included for formatting and readability. | extra spaces are included for formatting and readability. | |||
{ | { | |||
"typ":"dpop+jwt", | "typ":"dpop+jwt", | |||
"alg":"ES256", | "alg":"ES256", | |||
"jwk": { | "jwk": { | |||
skipping to change at page 11, line 23 ¶ | skipping to change at line 469 ¶ | |||
} | } | |||
} | } | |||
. | . | |||
{ | { | |||
"jti":"-BwC3ESc6acc2lTc", | "jti":"-BwC3ESc6acc2lTc", | |||
"htm":"POST", | "htm":"POST", | |||
"htu":"https://server.example.com/token", | "htu":"https://server.example.com/token", | |||
"iat":1562262616 | "iat":1562262616 | |||
} | } | |||
Figure 4: Example JWT content of a DPoP proof | Figure 4: Example JWT Content of a DPoP Proof | |||
Of the HTTP request, only the HTTP method and URI are included in the | Of the HTTP request, only the HTTP method and URI are included in the | |||
DPoP JWT, and therefore only these two message parts are covered by | DPoP JWT; therefore, only these two message parts are covered by the | |||
the DPoP proof. The idea is sign just enough of the HTTP data to | DPoP proof. The idea is to sign just enough of the HTTP data to | |||
provide reasonable proof-of-possession with respect to the HTTP | provide reasonable proof of possession with respect to the HTTP | |||
request. This design approach of using only a minimal subset of the | request. This design approach of using only a minimal subset of the | |||
HTTP header data is to avoid the substantial difficulties inherent in | HTTP header data is to avoid the substantial difficulties inherent in | |||
attempting to normalize HTTP messages. Nonetheless, DPoP proofs can | attempting to normalize HTTP messages. Nonetheless, DPoP proofs can | |||
be extended to contain other information of the HTTP request (see | be extended to contain other information of the HTTP request (see | |||
also Section 11.7). | also Section 11.7). | |||
4.3. Checking DPoP Proofs | 4.3. Checking DPoP Proofs | |||
To validate a DPoP proof, the receiving server MUST ensure that | To validate a DPoP proof, the receiving server MUST ensure the | |||
following: | ||||
1. there is not more than one DPoP HTTP request header field, | 1. There is not more than one DPoP HTTP request header field. | |||
2. the DPoP HTTP request header field value is a single well-formed | 2. The DPoP HTTP request header field value is a single and well- | |||
JWT, | formed JWT. | |||
3. all required claims per Section 4.2 are contained in the JWT, | 3. All required claims per Section 4.2 are contained in the JWT. | |||
4. the typ JOSE header parameter has the value dpop+jwt, | 4. The typ JOSE Header Parameter has the value dpop+jwt. | |||
5. the alg JOSE header parameter indicates a registered asymmetric | 5. The alg JOSE Header Parameter indicates a registered asymmetric | |||
digital signature algorithm [IANA.JOSE.ALGS], is not none, is | digital signature algorithm [IANA.JOSE.ALGS], is not none, is | |||
supported by the application, and is acceptable per local | supported by the application, and is acceptable per local | |||
policy, | policy. | |||
6. the JWT signature verifies with the public key contained in the | 6. The JWT signature verifies with the public key contained in the | |||
jwk JOSE header parameter, | jwk JOSE Header Parameter. | |||
7. the jwk JOSE header parameter does not contain a private key, | 7. The jwk JOSE Header Parameter does not contain a private key. | |||
8. the htm claim matches the HTTP method of the current request, | 8. The htm claim matches the HTTP method of the current request. | |||
9. the htu claim matches the HTTP URI value for the HTTP request in | 9. The htu claim matches the HTTP URI value for the HTTP request in | |||
which the JWT was received, ignoring any query and fragment | which the JWT was received, ignoring any query and fragment | |||
parts, | parts. | |||
10. if the server provided a nonce value to the client, the nonce | 10. If the server provided a nonce value to the client, the nonce | |||
claim matches the server-provided nonce value, | claim matches the server-provided nonce value. | |||
11. the creation time of the JWT, as determined by either the iat | 11. The creation time of the JWT, as determined by either the iat | |||
claim or a server managed timestamp via the nonce claim, is | claim or a server managed timestamp via the nonce claim, is | |||
within an acceptable window (see Section 11.1), | within an acceptable window (see Section 11.1). | |||
12. if presented to a protected resource in conjunction with an | 12. If presented to a protected resource in conjunction with an | |||
access token, | access token, | |||
* ensure that the value of the ath claim equals the hash of | * ensure that the value of the ath claim equals the hash of | |||
that access token, | that access token, and | |||
* confirm that the public key to which the access token is | * confirm that the public key to which the access token is | |||
bound matches the public key from the DPoP proof. | bound matches the public key from the DPoP proof. | |||
To reduce the likelihood of false negatives, servers SHOULD employ | To reduce the likelihood of false negatives, servers SHOULD employ | |||
Syntax-Based Normalization (Section 6.2.2 of [RFC3986]) and Scheme- | syntax-based normalization (Section 6.2.2 of [RFC3986]) and scheme- | |||
Based Normalization (Section 6.2.3 of [RFC3986]) before comparing the | based normalization (Section 6.2.3 of [RFC3986]) before comparing the | |||
htu claim. | htu claim. | |||
These checks may be performed in any order. | These checks may be performed in any order. | |||
5. DPoP Access Token Request | 5. DPoP Access Token Request | |||
To request an access token that is bound to a public key using DPoP, | To request an access token that is bound to a public key using DPoP, | |||
the client MUST provide a valid DPoP proof JWT in a DPoP header when | the client MUST provide a valid DPoP proof JWT in a DPoP header when | |||
making an access token request to the authorization server's token | making an access token request to the authorization server's token | |||
endpoint. This is applicable for all access token requests | endpoint. This is applicable for all access token requests | |||
regardless of grant type (including, for example, the common | regardless of grant type (e.g., the common authorization_code and | |||
authorization_code and refresh_token grant types but also extension | refresh_token grant types and extension grants such as the JWT | |||
grants such as the JWT authorization grant [RFC7523]). The HTTP | authorization grant [RFC7523]). The HTTP request shown in Figure 5 | |||
request shown in Figure 5 illustrates such an access token request | illustrates such an access token request using an authorization code | |||
using an authorization code grant with a DPoP proof JWT in the DPoP | grant with a DPoP proof JWT in the DPoP header. Figure 5 uses "\" | |||
header (with '\' line wrapping per RFC 8792). | line wrapping per [RFC8792]. | |||
POST /token HTTP/1.1 | POST /token HTTP/1.1 | |||
Host: server.example.com | Host: server.example.com | |||
Content-Type: application/x-www-form-urlencoded | Content-Type: application/x-www-form-urlencoded | |||
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ | DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ | |||
VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ | VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ | |||
nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ | nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ | |||
QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\ | QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\ | |||
oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\ | oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\ | |||
WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\ | WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\ | |||
4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg | 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg | |||
grant_type=authorization_code\ | grant_type=authorization_code\ | |||
&client_id=s6BhdRkqt\ | &client_id=s6BhdRkqt\ | |||
&code=SplxlOBeZQQYbYS6WxSbIA | &code=SplxlOBeZQQYbYS6WxSbIA | |||
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\ | &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\ | |||
&code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz- | &code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz- | |||
Figure 5: Token Request for a DPoP sender-constrained token using an | Figure 5: Token Request for a DPoP Sender-Constrained Token Using an | |||
authorization code | Authorization Code | |||
The DPoP HTTP header field MUST contain a valid DPoP proof JWT. If | The DPoP HTTP header field MUST contain a valid DPoP proof JWT. If | |||
the DPoP proof is invalid, the authorization server issues an error | the DPoP proof is invalid, the authorization server issues an error | |||
response per Section 5.2 of [RFC6749] with invalid_dpop_proof as the | response per Section 5.2 of [RFC6749] with invalid_dpop_proof as the | |||
value of the error parameter. | value of the error parameter. | |||
To sender-constrain the access token, after checking the validity of | To sender-constrain the access token after checking the validity of | |||
the DPoP proof, the authorization server associates the issued access | the DPoP proof, the authorization server associates the issued access | |||
token with the public key from the DPoP proof, which can be | token with the public key from the DPoP proof, which can be | |||
accomplished as described in Section 6. A token_type of DPoP MUST be | accomplished as described in Section 6. A token_type of DPoP MUST be | |||
included in the access token response to signal to the client that | included in the access token response to signal to the client that | |||
the access token was bound to its DPoP key and can be used as | the access token was bound to its DPoP key and can be used as | |||
described in Section 7.1. The example response shown in Figure 6 | described in Section 7.1. The example response shown in Figure 6 | |||
illustrates such a response. | illustrates such a response. | |||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Content-Type: application/json | Content-Type: application/json | |||
skipping to change at page 14, line 5 ¶ | skipping to change at line 581 ¶ | |||
{ | { | |||
"access_token": "Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU", | "access_token": "Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU", | |||
"token_type": "DPoP", | "token_type": "DPoP", | |||
"expires_in": 2677, | "expires_in": 2677, | |||
"refresh_token": "Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g" | "refresh_token": "Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g" | |||
} | } | |||
Figure 6: Access Token Response | Figure 6: Access Token Response | |||
The example response in Figure 6 includes a refresh token which the | The example response in Figure 6 includes a refresh token that the | |||
client can use to obtain a new access token when the previous one | client can use to obtain a new access token when the previous one | |||
expires. Refreshing an access token is a token request using the | expires. Refreshing an access token is a token request using the | |||
refresh_token grant type made to the authorization server's token | refresh_token grant type made to the authorization server's token | |||
endpoint. As with all access token requests, the client makes it a | endpoint. As with all access token requests, the client makes it a | |||
DPoP request by including a DPoP proof, as shown in the Figure 7 | DPoP request by including a DPoP proof, as shown in Figure 7. | |||
example (with '\' line wrapping per RFC 8792). | Figure 7 uses "\" line wrapping per [RFC8792]. | |||
POST /token HTTP/1.1 | POST /token HTTP/1.1 | |||
Host: server.example.com | Host: server.example.com | |||
Content-Type: application/x-www-form-urlencoded | Content-Type: application/x-www-form-urlencoded | |||
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ | DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ | |||
VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ | VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ | |||
nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ | nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ | |||
QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\ | QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\ | |||
oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\ | oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\ | |||
WF0IjoxNTYyMjY1Mjk2fQ.pAqut2IRDm_De6PR93SYmGBPXpwrAk90e8cP2hjiaG5Qs\ | WF0IjoxNTYyMjY1Mjk2fQ.pAqut2IRDm_De6PR93SYmGBPXpwrAk90e8cP2hjiaG5Qs\ | |||
GSuKDYW7_X620BxqhvYC8ynrrvZLTk41mSRroapUA | GSuKDYW7_X620BxqhvYC8ynrrvZLTk41mSRroapUA | |||
grant_type=refresh_token\ | grant_type=refresh_token\ | |||
&client_id=s6BhdRkqt\ | &client_id=s6BhdRkqt\ | |||
&refresh_token=Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g | &refresh_token=Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g | |||
Figure 7: Token Request for a DPoP-bound Token using a Refresh Token | Figure 7: Token Request for a DPoP-Bound Token Using a Refresh Token | |||
When an authorization server supporting DPoP issues a refresh token | When an authorization server supporting DPoP issues a refresh token | |||
to a public client that presents a valid DPoP proof at the token | to a public client that presents a valid DPoP proof at the token | |||
endpoint, the refresh token MUST be bound to the respective public | endpoint, the refresh token MUST be bound to the respective public | |||
key. The binding MUST be validated when the refresh token is later | key. The binding MUST be validated when the refresh token is later | |||
presented to get new access tokens. As a result, such a client MUST | presented to get new access tokens. As a result, such a client MUST | |||
present a DPoP proof for the same key that was used to obtain the | present a DPoP proof for the same key that was used to obtain the | |||
refresh token each time that refresh token is used to obtain a new | refresh token each time that refresh token is used to obtain a new | |||
access token. The implementation details of the binding of the | access token. The implementation details of the binding of the | |||
refresh token are at the discretion of the authorization server. | refresh token are at the discretion of the authorization server. | |||
Since the authorization server both produces and validates its | Since the authorization server both produces and validates its | |||
refresh tokens, there is no interoperability consideration in the | refresh tokens, there is no interoperability consideration in the | |||
specific details of the binding. | specific details of the binding. | |||
An authorization server MAY elect to issue access tokens which are | An authorization server MAY elect to issue access tokens that are not | |||
not DPoP bound, which is signaled to the client with a value of | DPoP bound, which is signaled to the client with a value of Bearer in | |||
Bearer in the token_type parameter of the access token response per | the token_type parameter of the access token response per [RFC6750]. | |||
[RFC6750]. For a public client that is also issued a refresh token, | For a public client that is also issued a refresh token, this has the | |||
this has the effect of DPoP-binding the refresh token alone, which | effect of DPoP-binding the refresh token alone, which can improve the | |||
can improve the security posture even when protected resources are | security posture even when protected resources are not updated to | |||
not updated to support DPoP. | support DPoP. | |||
If the access token response contains a different token_type value | If the access token response contains a different token_type value | |||
than DPoP, the access token protection provided by DPoP is not given. | than DPoP, the access token protection provided by DPoP is not given. | |||
The client MUST discard the response in this case, if this protection | The client MUST discard the response in this case if this protection | |||
is deemed important for the security of the application; otherwise, | is deemed important for the security of the application; otherwise, | |||
it may continue as in a regular OAuth interaction. | the client may continue as in a regular OAuth interaction. | |||
Refresh tokens issued to confidential clients (those having | Refresh tokens issued to confidential clients (those having | |||
established authentication credentials with the authorization server) | established authentication credentials with the authorization server) | |||
are not bound to the DPoP proof public key because they are already | are not bound to the DPoP proof public key because they are already | |||
sender-constrained with a different existing mechanism. The OAuth | sender-constrained with a different existing mechanism. The OAuth | |||
2.0 Authorization Framework [RFC6749] already requires that an | 2.0 Authorization Framework [RFC6749] already requires that an | |||
authorization server bind refresh tokens to the client to which they | authorization server bind refresh tokens to the client to which they | |||
were issued and that confidential clients authenticate to the | were issued and that confidential clients authenticate to the | |||
authorization server when presenting a refresh token. As a result, | authorization server when presenting a refresh token. As a result, | |||
such refresh tokens are sender-constrained by way of the client | such refresh tokens are sender-constrained by way of the client | |||
skipping to change at page 15, line 32 ¶ | skipping to change at line 654 ¶ | |||
allows credential rotation for the client without invalidating | allows credential rotation for the client without invalidating | |||
refresh tokens) than binding directly to a particular public key. | refresh tokens) than binding directly to a particular public key. | |||
5.1. Authorization Server Metadata | 5.1. Authorization Server Metadata | |||
This document introduces the following authorization server metadata | This document introduces the following authorization server metadata | |||
[RFC8414] parameter to signal support for DPoP in general and the | [RFC8414] parameter to signal support for DPoP in general and the | |||
specific JWS alg values the authorization server supports for DPoP | specific JWS alg values the authorization server supports for DPoP | |||
proof JWTs. | proof JWTs. | |||
dpop_signing_alg_values_supported A JSON array containing a list of | dpop_signing_alg_values_supported: A JSON array containing a list of | |||
the JWS alg values (from the [IANA.JOSE.ALGS] registry) supported | the JWS alg values (from the [IANA.JOSE.ALGS] registry) supported | |||
by the authorization server for DPoP proof JWTs. | by the authorization server for DPoP proof JWTs. | |||
5.2. Client Registration Metadata | 5.2. Client Registration Metadata | |||
The Dynamic Client Registration Protocol [RFC7591] defines an API for | The Dynamic Client Registration Protocol [RFC7591] defines an API for | |||
dynamically registering OAuth 2.0 client metadata with authorization | dynamically registering OAuth 2.0 client metadata with authorization | |||
servers. The metadata defined by [RFC7591], and registered | servers. The metadata defined by [RFC7591], and registered | |||
extensions to it, also imply a general data model for clients that is | extensions to it, also imply a general data model for clients that is | |||
useful for authorization server implementations even when the Dynamic | useful for authorization server implementations even when the Dynamic | |||
Client Registration Protocol isn't in play. Such implementations | Client Registration Protocol isn't in play. Such implementations | |||
will typically have some sort of user interface available for | will typically have some sort of user interface available for | |||
managing client configuration. | managing client configuration. | |||
This document introduces the following client registration metadata | This document introduces the following client registration metadata | |||
[RFC7591] parameter to indicate that the client always uses DPoP when | [RFC7591] parameter to indicate that the client always uses DPoP when | |||
requesting tokens from the authorization server. | requesting tokens from the authorization server. | |||
dpop_bound_access_tokens Boolean value specifying whether the client | dpop_bound_access_tokens: A boolean value specifying whether the | |||
always uses DPoP for token requests. If omitted, the default | client always uses DPoP for token requests. If omitted, the | |||
value is false. | default value is false. | |||
If true, the authorization server MUST reject token requests from | If the value is true, the authorization server MUST reject token | |||
this client that do not contain the DPoP header. | requests from the client that do not contain the DPoP header. | |||
6. Public Key Confirmation | 6. Public Key Confirmation | |||
Resource servers MUST be able to reliably identify whether an access | Resource servers MUST be able to reliably identify whether an access | |||
token is DPoP-bound and ascertain sufficient information to verify | token is DPoP-bound and ascertain sufficient information to verify | |||
the binding to the public key of the DPoP proof (see Section 7.1). | the binding to the public key of the DPoP proof (see Section 7.1). | |||
Such a binding is accomplished by associating the public key with the | Such a binding is accomplished by associating the public key with the | |||
token in a way that can be accessed by the protected resource, such | token in a way that can be accessed by the protected resource, such | |||
as embedding the JWK hash in the issued access token directly, using | as embedding the JWK hash in the issued access token directly, using | |||
the syntax described in Section 6.1, or through token introspection | the syntax described in Section 6.1, or through token introspection | |||
as described in Section 6.2. Other methods of associating a public | as described in Section 6.2. Other methods of associating a public | |||
key with an access token are possible, per agreement by the | key with an access token are possible per an agreement by the | |||
authorization server and the protected resource, but are beyond the | authorization server and the protected resource; however, they are | |||
scope of this specification. | beyond the scope of this specification. | |||
Resource servers supporting DPoP MUST ensure that the public key from | Resource servers supporting DPoP MUST ensure that the public key from | |||
the DPoP proof matches the one bound to the access token. | the DPoP proof matches the one bound to the access token. | |||
6.1. JWK Thumbprint Confirmation Method | 6.1. JWK Thumbprint Confirmation Method | |||
When access tokens are represented as JWTs [RFC7519], the public key | When access tokens are represented as JWTs [RFC7519], the public key | |||
information is represented using the jkt confirmation method member | information is represented using the jkt confirmation method member | |||
defined herein. To convey the hash of a public key in a JWT, this | defined herein. To convey the hash of a public key in a JWT, this | |||
specification introduces the following JWT Confirmation Method | specification introduces the following JWT Confirmation Method | |||
[RFC7800] member for use under the cnf claim. | [RFC7800] member for use under the cnf claim. | |||
jkt JWK SHA-256 Thumbprint Confirmation Method. The value of the | jkt: JWK SHA-256 Thumbprint confirmation method. The value of the | |||
jkt member MUST be the base64url encoding (as defined in | jkt member MUST be the base64url encoding (as defined in | |||
[RFC7515]) of the JWK SHA-256 Thumbprint (according to [RFC7638]) | [RFC7515]) of the JWK SHA-256 Thumbprint (according to [RFC7638]) | |||
of the DPoP public key (in JWK format) to which the access token | of the DPoP public key (in JWK format) to which the access token | |||
is bound. | is bound. | |||
The following example JWT in Figure 8 with decoded JWT payload shown | The following example JWT in Figure 8 with a decoded JWT payload | |||
in Figure 9 contains a cnf claim with the jkt JWK Thumbprint | shown in Figure 9 contains a cnf claim with the jkt JWK Thumbprint | |||
confirmation method member. The jkt value in these examples is the | confirmation method member. The jkt value in these examples is the | |||
hash of the public key from the DPoP proofs in the examples in | hash of the public key from the DPoP proofs in the examples shown in | |||
Section 5. (The example uses '\' line wrapping per RFC 8792.) | Section 5. The example uses "\" line wrapping per [RFC8792]. | |||
eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWIiOiJzb21lb25lQGV4YW1\ | eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWIiOiJzb21lb25lQGV4YW1\ | |||
wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJuYmYiOjE\ | wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJuYmYiOjE\ | |||
1NjIyNjI2MTEsImV4cCI6MTU2MjI2NjIxNiwiY25mIjp7ImprdCI6IjBaY09DT1JaTll\ | 1NjIyNjI2MTEsImV4cCI6MTU2MjI2NjIxNiwiY25mIjp7ImprdCI6IjBaY09DT1JaTll\ | |||
5LURXcHFxMzBqWnlKR0hUTjBkMkhnbEJWM3VpZ3VBNEkifX0.3Tyo8VTcn6u_PboUmAO\ | 5LURXcHFxMzBqWnlKR0hUTjBkMkhnbEJWM3VpZ3VBNEkifX0.3Tyo8VTcn6u_PboUmAO\ | |||
YUY1kfAavomW_YwYMkmRNizLJoQzWy2fCo79Zi5yObpIzjWb5xW4OGld7ESZrh0fsrA | YUY1kfAavomW_YwYMkmRNizLJoQzWy2fCo79Zi5yObpIzjWb5xW4OGld7ESZrh0fsrA | |||
Figure 8: JWT containing a JWK SHA-256 Thumbprint Confirmation | ||||
Figure 8: JWT Containing a JWK SHA-256 Thumbprint Confirmation | ||||
{ | { | |||
"sub":"someone@example.com", | "sub":"someone@example.com", | |||
"iss":"https://server.example.com", | "iss":"https://server.example.com", | |||
"nbf":1562262611, | "nbf":1562262611, | |||
"exp":1562266216, | "exp":1562266216, | |||
"cnf": | "cnf": | |||
{ | { | |||
"jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" | "jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" | |||
} | } | |||
} | } | |||
Figure 9: JWT Claims Set with a JWK SHA-256 Thumbprint Confirmation | Figure 9: JWT Claims Set with a JWK SHA-256 Thumbprint Confirmation | |||
6.2. JWK Thumbprint Confirmation Method in Token Introspection | 6.2. JWK Thumbprint Confirmation Method in Token Introspection | |||
OAuth 2.0 Token Introspection [RFC7662] defines a method for a | "OAuth 2.0 Token Introspection" [RFC7662] defines a method for a | |||
protected resource to query an authorization server about the active | protected resource to query an authorization server about the active | |||
state of an access token as well as to determine metainformation | state of an access token. The protected resource also determines | |||
about the token. | metainformation about the token. | |||
For a DPoP-bound access token, the hash of the public key to which | For a DPoP-bound access token, the hash of the public key to which | |||
the token is bound is conveyed to the protected resource as | the token is bound is conveyed to the protected resource as | |||
metainformation in a token introspection response. The hash is | metainformation in a token introspection response. The hash is | |||
conveyed using the same cnf content with jkt member structure as the | conveyed using the same cnf content with jkt member structure as the | |||
JWK Thumbprint confirmation method, described in Section 6.1, as a | JWK Thumbprint confirmation method, described in Section 6.1, as a | |||
top-level member of the introspection response JSON. Note that the | top-level member of the introspection response JSON. Note that the | |||
resource server does not send a DPoP proof with the introspection | resource server does not send a DPoP proof with the introspection | |||
request and the authorization server does not validate an access | request, and the authorization server does not validate an access | |||
token's DPoP binding at the introspection endpoint. Rather the | token's DPoP binding at the introspection endpoint. Rather, the | |||
resource server uses the data of the introspection response to | resource server uses the data of the introspection response to | |||
validate the access token binding itself locally. | validate the access token binding itself locally. | |||
If the token_type member is included in the introspection response, | If the token_type member is included in the introspection response, | |||
it MUST contain the value DPoP. | it MUST contain the value DPoP. | |||
The example introspection request in Figure 10 and corresponding | The example introspection request in Figure 10 and corresponding | |||
response in Figure 11 illustrate an introspection exchange for the | response in Figure 11 illustrate an introspection exchange for the | |||
example DPoP-bound access token that was issued in Figure 6. | example DPoP-bound access token that was issued in Figure 6. | |||
skipping to change at page 18, line 27 ¶ | skipping to change at line 794 ¶ | |||
{ | { | |||
"jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" | "jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" | |||
} | } | |||
} | } | |||
Figure 11: Example Introspection Response for a DPoP-Bound Access | Figure 11: Example Introspection Response for a DPoP-Bound Access | |||
Token | Token | |||
7. Protected Resource Access | 7. Protected Resource Access | |||
Requests to DPoP protected resources MUST include both a DPoP proof | Requests to DPoP-protected resources MUST include both a DPoP proof | |||
as per Section 4 and the access token as described in Section 7.1. | as per Section 4 and the access token as described in Section 7.1. | |||
The DPoP proof MUST include the ath claim with a valid hash of the | The DPoP proof MUST include the ath claim with a valid hash of the | |||
associated access token. | associated access token. | |||
Binding the token value to the proof in this way prevents a proof to | Binding the token value to the proof in this way prevents a proof to | |||
be used with multiple different access token values across different | be used with multiple different access token values across different | |||
requests. For example, if a client holds tokens bound to two | requests. For example, if a client holds tokens bound to two | |||
different resource owners, AT1 and AT2, and uses the same key when | different resource owners, AT1 and AT2, and uses the same key when | |||
talking to the AS, it's possible that these tokens could be swapped. | talking to the authorization server, it's possible that these tokens | |||
Without the ath field to bind it, a captured signature applied to AT1 | could be swapped. Without the ath field to bind it, a captured | |||
could be replayed with AT2 instead, changing the rights and access of | signature applied to AT1 could be replayed with AT2 instead, changing | |||
the intended request. This same substitution prevention remains for | the rights and access of the intended request. This same | |||
rotated access tokens within the same combination of client and | substitution prevention remains for rotated access tokens within the | |||
resource owner -- a rotated token value would require the calculation | same combination of client and resource owner -- a rotated token | |||
of a new proof. This binding additionally ensures that a proof | value would require the calculation of a new proof. This binding | |||
intended for use with the access token is not usable without an | additionally ensures that a proof intended for use with the access | |||
access token, or vice-versa. | token is not usable without an access token, or vice-versa. | |||
The resource server is required to calculate the hash of the token | The resource server is required to calculate the hash of the token | |||
value presented and verify that it is the same as the hash value in | value presented and verify that it is the same as the hash value in | |||
the ath field as described in Section 4.3. Since the ath field value | the ath field as described in Section 4.3. Since the ath field value | |||
is covered by the DPoP proof's signature, its inclusion binds the | is covered by the DPoP proof's signature, its inclusion binds the | |||
access token value to the holder of the key used to generate the | access token value to the holder of the key used to generate the | |||
signature. | signature. | |||
Note that the ath field alone does not prevent replay of the DPoP | Note that the ath field alone does not prevent replay of the DPoP | |||
proof or provide binding to the request in which the proof is | proof or provide binding to the request in which the proof is | |||
presented, and it is still important to check the time window of the | presented, and it is still important to check the time window of the | |||
proof as well as the included message parameters such as htm and htu. | proof as well as the included message parameters, such as htm and | |||
htu. | ||||
7.1. The DPoP Authentication Scheme | 7.1. The DPoP Authentication Scheme | |||
A DPoP-bound access token is sent using the Authorization request | A DPoP-bound access token is sent using the Authorization request | |||
header field per Section 11.6.2 of [RFC9110] using an authentication | header field per Section 11.6.2 of [RFC9110] with an authentication | |||
scheme of DPoP. The syntax of the Authorization header field for the | scheme of DPoP. The syntax of the Authorization header field for the | |||
DPoP scheme uses the token68 syntax defined in Section 11.2 of | DPoP scheme uses the token68 syntax defined in Section 11.2 of | |||
[RFC9110] (repeated below for ease of reference) for credentials. | [RFC9110] for credentials and is repeated below for ease of | |||
The ABNF notation syntax for DPoP authentication scheme credentials | reference. The ABNF notation syntax for DPoP authentication scheme | |||
is as follows: | credentials is as follows: | |||
token68 = 1*( ALPHA / DIGIT / | token68 = 1*( ALPHA / DIGIT / | |||
"-" / "." / "_" / "~" / "+" / "/" ) *"=" | "-" / "." / "_" / "~" / "+" / "/" ) *"=" | |||
credentials = "DPoP" 1*SP token68 | credentials = "DPoP" 1*SP token68 | |||
Figure 12: DPoP Authentication Scheme ABNF | Figure 12: DPoP Authentication Scheme ABNF | |||
For such an access token, a resource server MUST check that a DPoP | For such an access token, a resource server MUST check that a DPoP | |||
proof was also received in the DPoP header field of the HTTP request, | proof was also received in the DPoP header field of the HTTP request, | |||
check the DPoP proof according to the rules in Section 4.3, and check | check the DPoP proof according to the rules in Section 4.3, and check | |||
that the public key of the DPoP proof matches the public key to which | that the public key of the DPoP proof matches the public key to which | |||
the access token is bound per Section 6. | the access token is bound per Section 6. | |||
The resource server MUST NOT grant access to the resource unless all | The resource server MUST NOT grant access to the resource unless all | |||
checks are successful. | checks are successful. | |||
Figure 13 shows an example request to a protected resource with a | Figure 13 shows an example request to a protected resource with a | |||
DPoP-bound access token in the Authorization header and the DPoP | DPoP-bound access token in the Authorization header and the DPoP | |||
proof in the DPoP header (with '\' line wrapping per RFC 8792). | proof in the DPoP header. The example uses "\" line wrapping per | |||
Following that is Figure 14, which shows the decoded content of that | [RFC8792]. Figure 14 shows the decoded content of that DPoP proof. | |||
DPoP proof. The JSON of the JWT header and payload are shown but the | The JSON of the JWT header and payload are shown, but the signature | |||
signature part is omitted. As usual, line breaks and indentation are | part is omitted. As usual, line breaks and indentation are included | |||
included for formatting and readability. | for formatting and readability. | |||
GET /protectedresource HTTP/1.1 | GET /protectedresource HTTP/1.1 | |||
Host: resource.example.org | Host: resource.example.org | |||
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU | Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU | |||
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ | DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ | |||
VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ | VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ | |||
nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ | nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ | |||
QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj\ | QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj\ | |||
oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z\ | oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z\ | |||
WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF\ | WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF\ | |||
c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E\ | c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E\ | |||
OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA | OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA | |||
Figure 13: DPoP Protected Resource Request | Figure 13: DPoP-Protected Resource Request | |||
{ | { | |||
"typ":"dpop+jwt", | "typ":"dpop+jwt", | |||
"alg":"ES256", | "alg":"ES256", | |||
"jwk": { | "jwk": { | |||
"kty":"EC", | "kty":"EC", | |||
"x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs", | "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs", | |||
"y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA", | "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA", | |||
"crv":"P-256" | "crv":"P-256" | |||
} | } | |||
skipping to change at page 20, line 41 ¶ | skipping to change at line 896 ¶ | |||
"jti":"e1j3V_bKic8-LAEB", | "jti":"e1j3V_bKic8-LAEB", | |||
"htm":"GET", | "htm":"GET", | |||
"htu":"https://resource.example.org/protectedresource", | "htu":"https://resource.example.org/protectedresource", | |||
"iat":1562262618, | "iat":1562262618, | |||
"ath":"fUHyO2r2Z3DZ53EsNrWBb0xWXoaNy59IiKCAqksmQEo" | "ath":"fUHyO2r2Z3DZ53EsNrWBb0xWXoaNy59IiKCAqksmQEo" | |||
} | } | |||
Figure 14: Decoded Content of the DPoP Proof JWT in Figure 13 | Figure 14: Decoded Content of the DPoP Proof JWT in Figure 13 | |||
Upon receipt of a request to a protected resource within the | Upon receipt of a request to a protected resource within the | |||
protection space requiring DPoP authentication, if the request does | protection space requiring DPoP authentication, the server can | |||
not include valid credentials or does not contain an access token | respond with a challenge to the client to provide DPoP authentication | |||
sufficient for access, the server can respond with a challenge to the | information if the request does not include valid credentials or does | |||
client to provide DPoP authentication information. Such a challenge | not contain an access token sufficient for access. Such a challenge | |||
is made using the 401 (Unauthorized) response status code ([RFC9110], | is made using the 401 (Unauthorized) response status code ([RFC9110], | |||
Section 15.5.2) and the WWW-Authenticate header field ([RFC9110], | Section 15.5.2) and the WWW-Authenticate header field ([RFC9110], | |||
Section 11.6.1). The server MAY include the WWW-Authenticate header | Section 11.6.1). The server MAY include the WWW-Authenticate header | |||
in response to other conditions as well. | in response to other conditions as well. | |||
In such challenges: | In such challenges: | |||
* The scheme name is DPoP. | * The scheme name is DPoP. | |||
* The authentication parameter realm MAY be included to indicate the | * The authentication parameter realm MAY be included to indicate the | |||
scope of protection in the manner described in [RFC9110], | scope of protection in the manner described in [RFC9110], | |||
Section 11.5. | Section 11.5. | |||
* A scope authentication parameter MAY be included as defined in | * A scope authentication parameter MAY be included as defined in | |||
[RFC6750], Section 3. | [RFC6750], Section 3. | |||
* An error parameter ([RFC6750], Section 3) SHOULD be included to | * An error parameter ([RFC6750], Section 3) SHOULD be included to | |||
indicate the reason why the request was declined, if the request | indicate the reason why the request was declined, if the request | |||
included an access token but failed authentication. The error | included an access token but failed authentication. The error | |||
parameter values described in Section 3.1 of [RFC6750] are | parameter values described in [RFC6750], Section 3.1 are suitable, | |||
suitable as are any appropriate values defined by extension. The | as are any appropriate values defined by extension. The value | |||
value use_dpop_nonce can be used as described in Section 9 to | use_dpop_nonce can be used as described in Section 9 to signal | |||
signal that a nonce is needed in the DPoP proof of subsequent | that a nonce is needed in the DPoP proof of a subsequent | |||
request(s). And invalid_dpop_proof is used to indicate that the | request(s). Additionally, invalid_dpop_proof is used to indicate | |||
DPoP proof itself was deemed invalid based on the criteria of | that the DPoP proof itself was deemed invalid based on the | |||
Section 4.3. | criteria of Section 4.3. | |||
* An error_description parameter ([RFC6750], Section 3) MAY be | * An error_description parameter ([RFC6750], Section 3) MAY be | |||
included along with the error parameter to provide developers a | included along with the error parameter to provide developers a | |||
human-readable explanation that is not meant to be displayed to | human-readable explanation that is not meant to be displayed to | |||
end-users. | end-users. | |||
* An algs parameter SHOULD be included to signal to the client the | * An algs parameter SHOULD be included to signal to the client the | |||
JWS algorithms that are acceptable for the DPoP proof JWT. The | JWS algorithms that are acceptable for the DPoP proof JWT. The | |||
value of the parameter is a space-delimited list of JWS alg | value of the parameter is a space-delimited list of JWS alg | |||
(Algorithm) header values ([RFC7515], Section 4.1.1). | (Algorithm) header values ([RFC7515], Section 4.1.1). | |||
* Additional authentication parameters MAY be used and unknown | * Additional authentication parameters MAY be used, and unknown | |||
parameters MUST be ignored by recipients. | parameters MUST be ignored by recipients. | |||
For example, in response to a protected resource request without | Figure 15 shows a response to a protected resource request without | |||
authentication: | authentication. | |||
HTTP/1.1 401 Unauthorized | HTTP/1.1 401 Unauthorized | |||
WWW-Authenticate: DPoP algs="ES256 PS256" | WWW-Authenticate: DPoP algs="ES256 PS256" | |||
Figure 15: HTTP 401 Response to a Protected Resource Request without | Figure 15: HTTP 401 Response to a Protected Resource Request without | |||
Authentication | Authentication | |||
And in response to a protected resource request that was rejected | Figure 16 shows a response to a protected resource request that was | |||
because the confirmation of the DPoP binding in the access token | rejected due to the failed confirmation of the DPoP binding in the | |||
failed (with '\' line wrapping per RFC 8792): | access token. Figure 16 uses "\" line wrapping per [RFC8792]. | |||
HTTP/1.1 401 Unauthorized | HTTP/1.1 401 Unauthorized | |||
WWW-Authenticate: DPoP error="invalid_token", \ | WWW-Authenticate: DPoP error="invalid_token", \ | |||
error_description="Invalid DPoP key binding", algs="ES256" | error_description="Invalid DPoP key binding", algs="ES256" | |||
Figure 16: HTTP 401 Response to a Protected Resource Request with | Figure 16: HTTP 401 Response to a Protected Resource Request with | |||
an Invalid Token | an Invalid Token | |||
Note that browser-based client applications using CORS [WHATWG.Fetch] | Note that browser-based client applications using Cross-Origin | |||
only have access to CORS-safelisted response HTTP headers by default. | Resource Sharing (CORS) [WHATWG.Fetch] only have access to CORS- | |||
In order for the application to obtain and use the WWW-Authenticate | safelisted response HTTP headers by default. In order for the | |||
HTTP response header value, the server needs to make it available to | application to obtain and use the WWW-Authenticate HTTP response | |||
the application by including WWW-Authenticate in the Access-Control- | header value, the server needs to make it available to the | |||
application by including WWW-Authenticate in the Access-Control- | ||||
Expose-Headers response header list value. | Expose-Headers response header list value. | |||
This authentication scheme is for origin-server authentication only. | This authentication scheme is for origin-server authentication only. | |||
Therefore, this authentication scheme MUST NOT be used with the | Therefore, this authentication scheme MUST NOT be used with the | |||
Proxy-Authenticate or Proxy-Authorization header fields. | Proxy-Authenticate or Proxy-Authorization header fields. | |||
Note that the syntax of the Authorization header field for this | Note that the syntax of the Authorization header field for this | |||
authentication scheme follows the usage of the Bearer scheme defined | authentication scheme follows the usage of the Bearer scheme defined | |||
in Section 2.1 of [RFC6750]. While not the preferred credential | in Section 2.1 of [RFC6750]. While it is not the preferred | |||
syntax of [RFC9110], it is compatible with the general authentication | credential syntax of [RFC9110], it is compatible with the general | |||
framework therein and was used for consistency and familiarity with | authentication framework therein and is used for consistency and | |||
the Bearer scheme. | familiarity with the Bearer scheme. | |||
7.2. Compatibility with the Bearer Authentication Scheme | 7.2. Compatibility with the Bearer Authentication Scheme | |||
Protected resources simultaneously supporting both the DPoP and | Protected resources simultaneously supporting both the DPoP and | |||
Bearer schemes need to update how evaluation of bearer tokens is | Bearer schemes need to update how the evaluation process is performed | |||
performed to prevent downgraded usage of a DPoP-bound access token. | for bearer tokens to prevent downgraded usage of a DPoP-bound access | |||
Specifically, such a protected resource MUST reject a DPoP-bound | token. Specifically, such a protected resource MUST reject a DPoP- | |||
access token received as a bearer token per [RFC6750]. | bound access token received as a bearer token per [RFC6750]. | |||
Section 11.6.1 of [RFC9110] allows a protected resource to indicate | Section 11.6.1 of [RFC9110] allows a protected resource to indicate | |||
support for multiple authentication schemes (i.e., Bearer and DPoP) | support for multiple authentication schemes (i.e., Bearer and DPoP) | |||
with the WWW-Authenticate header field of a 401 (Unauthorized) | with the WWW-Authenticate header field of a 401 (Unauthorized) | |||
response. | response. | |||
A protected resource that supports only [RFC6750] and is unaware of | A protected resource that supports only [RFC6750] and is unaware of | |||
DPoP would most presumably accept a DPoP-bound access token as a | DPoP would most presumably accept a DPoP-bound access token as a | |||
bearer token (JWT [RFC7519] says to ignore unrecognized claims, | bearer token (JWT [RFC7519] says to ignore unrecognized claims, | |||
Introspection [RFC7662] says that other parameters might be present | Introspection [RFC7662] says that other parameters might be present | |||
while placing no functional requirements on their presence, and | while placing no functional requirements on their presence, and | |||
[RFC6750] is effectively silent on the content of the access token as | [RFC6750] is effectively silent on the content of the access token | |||
it relates to validity). As such, a client can send a DPoP-bound | since it relates to validity). As such, a client can send a DPoP- | |||
access token using the Bearer scheme upon receipt of a WWW- | bound access token using the Bearer scheme upon receipt of a WWW- | |||
Authenticate: Bearer challenge from a protected resource (or if it | Authenticate: Bearer challenge from a protected resource (or it can | |||
has prior such knowledge about the capabilities of the protected | send a DPoP-bound access token if it has prior knowledge of the | |||
resource). The effect of this likely simplifies the logistics of | capabilities of the protected resource). The effect of this likely | |||
phased upgrades to protected resources in their support DPoP or even | simplifies the logistics of phased upgrades to protected resources in | |||
prolonged deployments of protected resources with mixed token type | their support DPoP or prolonged deployments of protected resources | |||
support. | with mixed token type support. | |||
If a protected resource supporting both Bearer and DPoP schemes | If a protected resource supporting both Bearer and DPoP schemes | |||
elects to respond with multiple WWW-Authenticate challenges, | elects to respond with multiple WWW-Authenticate challenges, | |||
attention should be paid to which challenge(s) should deliver the | attention should be paid to which challenge(s) should deliver the | |||
actual error information. It is RECOMMENDED that the following rules | actual error information. It is RECOMMENDED that the following rules | |||
be adhered to: | be adhered to: | |||
* If no authentication information has been included with the | * If no authentication information has been included with the | |||
request, then the challenges SHOULD NOT include an error code or | request, then the challenges SHOULD NOT include an error code or | |||
other error information, as per [RFC6750], Section 3.1 | other error information, as per Section 3.1 of [RFC6750] | |||
(Figure 17). | (Figure 17). | |||
* If the mechanism used to attempt authentication could be | * If the mechanism used to attempt authentication could be | |||
established unambiguously, then the corresponding challenge SHOULD | established unambiguously, then the corresponding challenge SHOULD | |||
be used to deliver error information (Figure 18). | be used to deliver error information (Figure 18). | |||
* Otherwise, both Bearer and DPoP challenged MAY be used to deliver | * Otherwise, both Bearer and DPoP challenges MAY be used to deliver | |||
error information (Figure 19). | error information (Figure 19). | |||
(Where needed, the following examples use '\' line wrapping per RFC | The following examples use "\" line wrapping per [RFC8792]. | |||
8792.) | ||||
GET /protectedresource HTTP/1.1 | GET /protectedresource HTTP/1.1 | |||
Host: resource.example.org | Host: resource.example.org | |||
HTTP/1.1 401 Unauthorized | HTTP/1.1 401 Unauthorized | |||
WWW-Authenticate: Bearer, DPoP algs="ES256 PS256" | WWW-Authenticate: Bearer, DPoP algs="ES256 PS256" | |||
Figure 17: HTTP 401 Response to a Protected Resource Request without | Figure 17: HTTP 401 Response to a Protected Resource Request without | |||
Authentication | Authentication | |||
skipping to change at page 24, line 22 ¶ | skipping to change at line 1058 ¶ | |||
error_description="Multiple methods used to include access token", \ | error_description="Multiple methods used to include access token", \ | |||
DPoP algs="ES256 PS256", error="invalid_request", \ | DPoP algs="ES256 PS256", error="invalid_request", \ | |||
error_description="Multiple methods used to include access token" | error_description="Multiple methods used to include access token" | |||
Figure 19: HTTP 400 Response to a Protected Resource Request with | Figure 19: HTTP 400 Response to a Protected Resource Request with | |||
Ambiguous Authentication | Ambiguous Authentication | |||
7.3. Client Considerations | 7.3. Client Considerations | |||
Authorization including a DPoP proof may not be idempotent (depending | Authorization including a DPoP proof may not be idempotent (depending | |||
on server enforcement of jti, iat and nonce claims). Consequently, | on server enforcement of jti, iat, and nonce claims). Consequently, | |||
all previously idempotent requests for protected resources that were | all previously idempotent requests for protected resources that were | |||
previously idempotent may no longer be idempotent. It is RECOMMENDED | previously idempotent may no longer be idempotent. It is RECOMMENDED | |||
that clients generate a unique DPoP proof even when retrying | that clients generate a unique DPoP proof, even when retrying | |||
idempotent requests in response to HTTP errors generally understood | idempotent requests in response to HTTP errors generally understood | |||
as transient. | as transient. | |||
Clients that encounter frequent network errors may experience | Clients that encounter frequent network errors may experience | |||
additional challenges when interacting with servers with more strict | additional challenges when interacting with servers with stricter | |||
nonce validation implementations. | nonce validation implementations. | |||
8. Authorization Server-Provided Nonce | 8. Authorization Server-Provided Nonce | |||
This section specifies a mechanism using opaque nonces provided by | This section specifies a mechanism using opaque nonces provided by | |||
the server that can be used to limit the lifetime of DPoP proofs. | the server that can be used to limit the lifetime of DPoP proofs. | |||
Without employing such a mechanism, a malicious party controlling the | Without employing such a mechanism, a malicious party controlling the | |||
client (including potentially the end-user) can create DPoP proofs | client (potentially including the end-user) can create DPoP proofs | |||
for use arbitrarily far in the future. | for use arbitrarily far in the future. | |||
Including a nonce value contributed by the authorization server in | Including a nonce value contributed by the authorization server in | |||
the DPoP proof MAY be used by authorization servers to limit the | the DPoP proof MAY be used by authorization servers to limit the | |||
lifetime of DPoP proofs. The server determines when and if to issue | lifetime of DPoP proofs. The server determines when to issue a new | |||
a new DPoP nonce challenge thereby requiring the use of the nonce | DPoP nonce challenge and if it is needed, thereby requiring the use | |||
value in subsequent DPoP proofs. The logic through which the server | of the nonce value in subsequent DPoP proofs. The logic through | |||
makes that determination is out of scope of this document. | which the server makes that determination is out of scope of this | |||
document. | ||||
An authorization server MAY supply a nonce value to be included by | An authorization server MAY supply a nonce value to be included by | |||
the client in DPoP proofs sent. In this case, the authorization | the client in DPoP proofs sent. In this case, the authorization | |||
server responds to requests not including a nonce with an HTTP 400 | server responds to requests that do not include a nonce with an HTTP | |||
(Bad Request) error response per Section 5.2 of [RFC6749] using | 400 (Bad Request) error response per Section 5.2 of [RFC6749] using | |||
use_dpop_nonce as the error code value. The authorization server | use_dpop_nonce as the error code value. The authorization server | |||
includes a DPoP-Nonce HTTP header in the response supplying a nonce | includes a DPoP-Nonce HTTP header in the response supplying a nonce | |||
value to be used when sending the subsequent request. Nonce values | value to be used when sending the subsequent request. Nonce values | |||
MUST be unpredictable. This same error code is used when supplying a | MUST be unpredictable. This same error code is used when supplying a | |||
new nonce value when there was a nonce mismatch. The client will | new nonce value when there was a nonce mismatch. The client will | |||
typically retry the request with the new nonce value supplied upon | typically retry the request with the new nonce value supplied upon | |||
receiving a use_dpop_nonce error with an accompanying nonce value. | receiving a use_dpop_nonce error with an accompanying nonce value. | |||
For example, in response to a token request without a nonce when the | For example, in response to a token request without a nonce when the | |||
authorization server requires one, the authorization server can | authorization server requires one, the authorization server can | |||
skipping to change at page 25, line 32 ¶ | skipping to change at line 1118 ¶ | |||
"Authorization server requires nonce in DPoP proof" | "Authorization server requires nonce in DPoP proof" | |||
} | } | |||
Figure 20: HTTP 400 Response to a Token Request without a Nonce | Figure 20: HTTP 400 Response to a Token Request without a Nonce | |||
Other HTTP headers and JSON fields MAY also be included in the error | Other HTTP headers and JSON fields MAY also be included in the error | |||
response, but there MUST NOT be more than one DPoP-Nonce header. | response, but there MUST NOT be more than one DPoP-Nonce header. | |||
Upon receiving the nonce, the client is expected to retry its token | Upon receiving the nonce, the client is expected to retry its token | |||
request using a DPoP proof including the supplied nonce value in the | request using a DPoP proof including the supplied nonce value in the | |||
nonce claim of the DPoP proof. An example unencoded JWT Payload of | nonce claim of the DPoP proof. An example unencoded JWT payload of | |||
such a DPoP proof including a nonce is: | such a DPoP proof including a nonce is shown below. | |||
{ | { | |||
"jti": "-BwC3ESc6acc2lTc", | "jti": "-BwC3ESc6acc2lTc", | |||
"htm": "POST", | "htm": "POST", | |||
"htu": "https://server.example.com/token", | "htu": "https://server.example.com/token", | |||
"iat": 1562262616, | "iat": 1562262616, | |||
"nonce": "eyJ7S_zG.eyJH0-Z.HX4w-7v" | "nonce": "eyJ7S_zG.eyJH0-Z.HX4w-7v" | |||
} | } | |||
Figure 21: DPoP Proof Payload Including a Nonce Value | Figure 21: DPoP Proof Payload including a Nonce Value | |||
The nonce is opaque to the client. | The nonce is opaque to the client. | |||
If the nonce claim in the DPoP proof does not exactly match a nonce | If the nonce claim in the DPoP proof does not exactly match a nonce | |||
recently supplied by the authorization server to the client, the | recently supplied by the authorization server to the client, the | |||
authorization server MUST reject the request. The rejection response | authorization server MUST reject the request. The rejection response | |||
MAY include a DPoP-Nonce HTTP header providing a new nonce value to | MAY include a DPoP-Nonce HTTP header providing a new nonce value to | |||
use for subsequent requests. | use for subsequent requests. | |||
The intent is that clients need to keep only one nonce value and | The intent is that clients need to keep only one nonce value and | |||
servers keep a window of recent nonces. That said, transient | servers need to keep a window of recent nonces. That said, transient | |||
circumstances may arise in which the server's and client's stored | circumstances may arise in which the stored nonce values for the | |||
nonce values differ. However, this situation is self-correcting; | server and the client differ. However, this situation is self- | |||
with any rejection message, the server can send the client the nonce | correcting. With any rejection message, the server can send the | |||
value that the server wants it to use and the client can store that | client the nonce value it wants to use to the client, and the client | |||
nonce value and retry the request with it. Even if the client and/or | can store that nonce value and retry the request with it. Even if | |||
server discard their stored nonce values, that situation is also | the client and/or server discard their stored nonce values, that | |||
self-correcting because new nonce values can be communicated when | situation is also self-correcting because new nonce values can be | |||
responding to or retrying failed requests. | communicated when responding to or retrying failed requests. | |||
Note that browser-based client applications using CORS [WHATWG.Fetch] | Note that browser-based client applications using CORS [WHATWG.Fetch] | |||
only have access to CORS-safelisted response HTTP headers by default. | only have access to CORS-safelisted response HTTP headers by default. | |||
In order for the application to obtain and use the DPoP-Nonce HTTP | In order for the application to obtain and use the DPoP-Nonce HTTP | |||
response header value, the server needs to make it available to the | response header value, the server needs to make it available to the | |||
application by including DPoP-Nonce in the Access-Control-Expose- | application by including DPoP-Nonce in the Access-Control-Expose- | |||
Headers response header list value. | Headers response header list value. | |||
8.1. Nonce Syntax | 8.1. Nonce Syntax | |||
The nonce syntax in ABNF as used by [RFC6749] (which is the same as | The nonce syntax in ABNF as used by [RFC6749] (which is the same as | |||
the scope-token syntax) is: | the scope-token syntax) is shown below. | |||
nonce = 1*NQCHAR | nonce = 1*NQCHAR | |||
Figure 22: Nonce ABNF | Figure 22: Nonce ABNF | |||
8.2. Providing a New Nonce Value | 8.2. Providing a New Nonce Value | |||
It is up to the authorization server when to supply a new nonce value | It is up to the authorization server when to supply a new nonce value | |||
for the client to use. The client is expected to use the existing | for the client to use. The client is expected to use the existing | |||
supplied nonce in DPoP proofs until the server supplies a new nonce | supplied nonce in DPoP proofs until the server supplies a new nonce | |||
value. | value. | |||
The authorization server MAY supply the new nonce in the same way | The authorization server MAY supply the new nonce in the same way | |||
that the initial one was supplied: by using a DPoP-Nonce HTTP header | that the initial one was supplied: by using a DPoP-Nonce HTTP header | |||
in the response. The DPoP-Nonce HTTP header field uses the nonce | in the response. The DPoP-Nonce HTTP header field uses the nonce | |||
syntax defined in Section 8.1. Of course, each time this happens it | syntax defined in Section 8.1. Each time this happens, it requires | |||
requires an extra protocol round trip. | an extra protocol round trip. | |||
A more efficient manner of supplying a new nonce value is also | A more efficient manner of supplying a new nonce value is also | |||
defined -- by including a DPoP-Nonce HTTP header in the HTTP 200 (OK) | defined by including a DPoP-Nonce HTTP header in the HTTP 200 (OK) | |||
response from the previous request. The client MUST use the new | response from the previous request. The client MUST use the new | |||
nonce value supplied for the next token request, and for all | nonce value supplied for the next token request and for all | |||
subsequent token requests until the authorization server supplies a | subsequent token requests until the authorization server supplies a | |||
new nonce. | new nonce. | |||
Responses that include the DPoP-Nonce HTTP header should be | Responses that include the DPoP-Nonce HTTP header should be | |||
uncacheable (e.g., using Cache-Control: no-store in response to a GET | uncacheable (e.g., using Cache-Control: no-store in response to a GET | |||
request) to prevent the response being used to serve a subsequent | request) to prevent the response from being used to serve a | |||
request and a stale nonce value being used as a result. | subsequent request and a stale nonce value from being used as a | |||
result. | ||||
An example 200 OK response providing a new nonce value is: | An example 200 OK response providing a new nonce value is shown | |||
below. | ||||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Cache-Control: no-store | Cache-Control: no-store | |||
DPoP-Nonce: eyJ7S_zG.eyJbYu3.xQmBj-1 | DPoP-Nonce: eyJ7S_zG.eyJbYu3.xQmBj-1 | |||
Figure 23: HTTP 200 Response Providing the Next Nonce Value | Figure 23: HTTP 200 Response Providing the Next Nonce Value | |||
9. Resource Server-Provided Nonce | 9. Resource Server-Provided Nonce | |||
Resource servers can also choose to provide a nonce value to be | Resource servers can also choose to provide a nonce value to be | |||
included in DPoP proofs sent to them. They provide the nonce using | included in DPoP proofs sent to them. They provide the nonce using | |||
the DPoP-Nonce header in the same way that authorization servers do | the DPoP-Nonce header in the same way that authorization servers do | |||
as described in Section 8 and Section 8.2. The error signaling is | as described in Sections 8 and 8.2. The error signaling is performed | |||
performed as described in Section 7.1. Resource servers use an HTTP | as described in Section 7.1. Resource servers use an HTTP 401 | |||
401 (Unauthorized) error code with an accompanying WWW-Authenticate: | (Unauthorized) error code with an accompanying WWW-Authenticate: DPoP | |||
DPoP value and DPoP-Nonce value to accomplish this. | value and DPoP-Nonce value to accomplish this. | |||
For example, in response to a resource request without a nonce when | For example, in response to a resource request without a nonce when | |||
the resource server requires one, the resource server can respond | the resource server requires one, the resource server can respond | |||
with a DPoP-Nonce value such as the following to provide a nonce | with a DPoP-Nonce value such as the following to provide a nonce | |||
value to include in the DPoP proof (with '\' line wrapping per RFC | value to include in the DPoP proof. The example below uses "\" line | |||
8792): | wrapping per [RFC8792]. | |||
HTTP/1.1 401 Unauthorized | HTTP/1.1 401 Unauthorized | |||
WWW-Authenticate: DPoP error="use_dpop_nonce", \ | WWW-Authenticate: DPoP error="use_dpop_nonce", \ | |||
error_description="Resource server requires nonce in DPoP proof" | error_description="Resource server requires nonce in DPoP proof" | |||
DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v | DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v | |||
Figure 24: HTTP 401 Response to a Resource Request without a Nonce | Figure 24: HTTP 401 Response to a Resource Request without a Nonce | |||
Note that the nonces provided by an authorization server and a | Note that the nonces provided by an authorization server and a | |||
resource server are different and should not be confused with one | resource server are different and should not be confused with one | |||
another, since nonces will be only accepted by the server that issued | another since nonces will be only accepted by the server that issued | |||
them. Likewise, should a client use multiple authorization servers | them. Likewise, should a client use multiple authorization servers | |||
and/or resource servers, a nonce issued by any of them should be used | and/or resource servers, a nonce issued by any of them should be used | |||
only at the issuing server. Developers should also take care to not | only at the issuing server. Developers should also be careful to not | |||
confuse DPoP nonces with the OpenID Connect [OpenID.Core] ID Token | confuse DPoP nonces with the OpenID Connect [OpenID.Core] ID Token | |||
nonce. | nonce. | |||
10. Authorization Code Binding to DPoP Key | 10. Authorization Code Binding to a DPoP Key | |||
Binding the authorization code issued to the client's proof-of- | Binding the authorization code issued to the client's proof-of- | |||
possession key can enable end-to-end binding of the entire | possession key can enable end-to-end binding of the entire | |||
authorization flow. This specification defines the dpop_jkt | authorization flow. This specification defines the dpop_jkt | |||
authorization request parameter for this purpose. The value of the | authorization request parameter for this purpose. The value of the | |||
dpop_jkt authorization request parameter is the JSON Web Key (JWK) | dpop_jkt authorization request parameter is the JWK Thumbprint | |||
Thumbprint [RFC7638] of the proof-of-possession public key using the | [RFC7638] of the proof-of-possession public key using the SHA-256 | |||
SHA-256 hash function - the same value as used for the jkt | hash function, which is the same value as used for the jkt | |||
confirmation method defined in Section 6.1. | confirmation method defined in Section 6.1. | |||
When a token request is received, the authorization server computes | When a token request is received, the authorization server computes | |||
the JWK thumbprint of the proof-of-possession public key in the DPoP | the JWK Thumbprint of the proof-of-possession public key in the DPoP | |||
proof and verifies that it matches the dpop_jkt parameter value in | proof and verifies that it matches the dpop_jkt parameter value in | |||
the authorization request. If they do not match, it MUST reject the | the authorization request. If they do not match, it MUST reject the | |||
request. | request. | |||
An example authorization request using the dpop_jkt authorization | An example authorization request using the dpop_jkt authorization | |||
request parameter follows (with '\' line wrapping per RFC 8792): | request parameter is shown below and uses "\" line wrapping per | |||
[RFC8792]. | ||||
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz\ | GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz\ | |||
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\ | &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\ | |||
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM\ | &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM\ | |||
&code_challenge_method=S256\ | &code_challenge_method=S256\ | |||
&dpop_jkt=NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs HTTP/1.1 | &dpop_jkt=NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs HTTP/1.1 | |||
Host: server.example.com | Host: server.example.com | |||
Figure 25: Authorization Request using the dpop_jkt Parameter | Figure 25: Authorization Request Using the dpop_jkt Parameter | |||
Use of the dpop_jkt authorization request parameter is OPTIONAL. | Use of the dpop_jkt authorization request parameter is OPTIONAL. | |||
Note that the dpop_jkt authorization request parameter MAY also be | Note that the dpop_jkt authorization request parameter MAY also be | |||
used in combination with PKCE [RFC7636], which is recommended by | used in combination with Proof Key for Code Exchange (PKCE) | |||
[I-D.ietf-oauth-security-topics] as a countermeasure to authorization | [RFC7636], which is recommended by [SECURITY-TOPICS] as a | |||
code injection. The dpop_jkt authorization request parameter only | countermeasure to authorization code injection. The dpop_jkt | |||
provides similar protections when a unique DPoP key is used for each | authorization request parameter only provides similar protections | |||
authorization request. | when a unique DPoP key is used for each authorization request. | |||
10.1. DPoP with Pushed Authorization Requests | 10.1. DPoP with Pushed Authorization Requests | |||
When Pushed Authorization Requests (PAR, [RFC9126]) are used in | When Pushed Authorization Requests (PARs) [RFC9126] are used in | |||
conjunction with DPoP, there are two ways in which the DPoP key can | conjunction with DPoP, there are two ways in which the DPoP key can | |||
be communicated in the PAR request: | be communicated in the PAR request: | |||
* The dpop_jkt parameter can be used as described in Section 10 to | * The dpop_jkt parameter can be used as described in Section 10 to | |||
bind the issued authorization code to a specific key. In this | bind the issued authorization code to a specific key. In this | |||
case, dpop_jkt MUST be included alongside other authorization | case, dpop_jkt MUST be included alongside other authorization | |||
request parameters in the POST body of the PAR request. | request parameters in the POST body of the PAR request. | |||
* Alternatively, the DPoP header can be added to the PAR request. | * Alternatively, the DPoP header can be added to the PAR request. | |||
In this case, the authorization server MUST check the provided | In this case, the authorization server MUST check the provided | |||
DPoP proof JWT as defined in Section 4.3. It MUST further behave | DPoP proof JWT as defined in Section 4.3. It MUST further behave | |||
as if the contained public key's thumbprint was provided using | as if the contained public key's thumbprint was provided using | |||
dpop_jkt, i.e., reject the subsequent token request unless a DPoP | dpop_jkt, i.e., reject the subsequent token request unless a DPoP | |||
proof for the same key is provided. This can help to simplify the | proof for the same key is provided. This can help to simplify the | |||
implementation of the client, as it can "blindly" attach the DPoP | implementation of the client, as it can "blindly" attach the DPoP | |||
header to all requests to the authorization server regardless of | header to all requests to the authorization server regardless of | |||
the type of request. Additionally, it provides a stronger | the type of request. Additionally, it provides a stronger | |||
binding, as the DPoP header contains a proof of possession of the | binding, as the DPoP header contains a proof of possession of the | |||
private key. | private key. | |||
Both mechanisms MUST be supported by an authorization server that | Both mechanisms MUST be supported by an authorization server that | |||
supports PAR and DPoP. If both mechanisms are used at the same time, | supports PAR and DPoP. If both mechanisms are used at the same time, | |||
the authorization server MUST reject the request if the JWK | the authorization server MUST reject the request if the JWK | |||
Thumbprint in dpop_jkt does not match the public key in the DPoP | Thumbprint in dpop_jkt does not match the public key in the DPoP | |||
header. | header. | |||
Allowing both mechanisms ensures that clients that use dpop_jkt do | Allowing both mechanisms ensures that clients using dpop_jkt do not | |||
not need to distinguish between front-channel and pushed | need to distinguish between front-channel and pushed authorization | |||
authorization requests, and at the same time, clients that only have | requests, and at the same time, clients that only have one code path | |||
one code path for protecting all calls to authorization server | for protecting all calls to authorization server endpoints do not | |||
endpoints do not need to distinguish between requests to the PAR | need to distinguish between requests to the PAR endpoint and the | |||
endpoint and the token endpoint. | token endpoint. | |||
11. Security Considerations | 11. Security Considerations | |||
In DPoP, the prevention of token replay at a different endpoint (see | In DPoP, the prevention of token replay at a different endpoint (see | |||
Section 2) is achieved through authentication of the server per | Section 2) is achieved through authentication of the server per | |||
[RFC6125] and binding of the DPoP proof to a certain URI and HTTP | [RFC6125] and the binding of the DPoP proof to a certain URI and HTTP | |||
method. DPoP, however, has a somewhat different nature of protection | method. However, DPoP has a somewhat different nature of protection | |||
than TLS-based methods such as OAuth Mutual TLS [RFC8705] or OAuth | than TLS-based methods such as OAuth Mutual TLS [RFC8705] or OAuth | |||
Token Binding [I-D.ietf-oauth-token-binding] (see also Section 11.1 | Token Binding [TOKEN-BINDING] (see also Sections 11.1 and 11.7). | |||
and Section 11.7). TLS-based mechanisms can leverage a tight | TLS-based mechanisms can leverage a tight integration between the TLS | |||
integration between the TLS layer and the application layer to | layer and the application layer to achieve strong message integrity, | |||
achieve strong message integrity, authenticity, and replay | authenticity, and replay protection. | |||
protection. | ||||
11.1. DPoP Proof Replay | 11.1. DPoP Proof Replay | |||
If an adversary is able to get hold of a DPoP proof JWT, the | If an adversary is able to get hold of a DPoP proof JWT, the | |||
adversary could replay that token at the same endpoint (the HTTP | adversary could replay that token at the same endpoint (the HTTP | |||
endpoint and method are enforced via the respective claims in the | endpoint and method are enforced via the respective claims in the | |||
JWTs). To limit this, servers MUST only accept DPoP proofs for a | JWTs). To limit this, servers MUST only accept DPoP proofs for a | |||
limited time after their creation (preferably only for a relatively | limited time after their creation (preferably only for a relatively | |||
brief period on the order of seconds or minutes). | brief period on the order of seconds or minutes). | |||
To prevent multiple uses of the same DPoP proof, servers can store, | In the context of the target URI, servers can store the jti value of | |||
in the context of the target URI, the jti value of each DPoP proof | each DPoP proof for the time window in which the respective DPoP | |||
for the time window in which the respective DPoP proof JWT would be | proof JWT would be accepted to prevent multiple uses of the same DPoP | |||
accepted. HTTP requests to the same URI for which the jti value has | proof. HTTP requests to the same URI for which the jti value has | |||
been seen before would be declined. Such a single-use check, when | been seen before would be declined. When strictly enforced, such a | |||
strictly enforced, provides a very strong protection against DPoP | single-use check provides a very strong protection against DPoP proof | |||
proof replay, but may not always be feasible in practice, e.g., when | replay, but it may not always be feasible in practice, e.g., when | |||
multiple servers behind a single endpoint have no shared state. | multiple servers behind a single endpoint have no shared state. | |||
In order to guard against memory exhaustion attacks, a server that is | In order to guard against memory exhaustion attacks, a server that is | |||
tracking jti values should reject DPoP proof JWTs with unnecessarily | tracking jti values should reject DPoP proof JWTs with unnecessarily | |||
large jti values or store only a hash thereof. | large jti values or store only a hash thereof. | |||
Note: To accommodate for clock offsets, the server MAY accept DPoP | Note: To accommodate for clock offsets, the server MAY accept DPoP | |||
proofs that carry an iat time in the reasonably near future (on the | proofs that carry an iat time in the reasonably near future (on the | |||
order of seconds or minutes). Because clock skews between servers | order of seconds or minutes). Because clock skews between servers | |||
and clients may be large, servers MAY limit DPoP proof lifetimes by | and clients may be large, servers MAY limit DPoP proof lifetimes by | |||
using server-provided nonce values containing the time at the server | using server-provided nonce values containing the time at the server | |||
rather than comparing the client-supplied iat time to the time at the | rather than comparing the client-supplied iat time to the time at the | |||
server. Nonces created in this way yield the same result even in the | server. Nonces created in this way yield the same result even in the | |||
face of arbitrarily large clock skews. | face of arbitrarily large clock skews. | |||
Server-provided nonces are an effective means for further reducing | Server-provided nonces are an effective means for further reducing | |||
the chances for successful DPoP proof replay. Unlike cryptographic | the chances for successful DPoP proof replay. Unlike cryptographic | |||
nonces, it is acceptable for clients to use the same nonce multiple | nonces, it is acceptable for clients to use the same nonce multiple | |||
times, and for the server to accept the same nonce multiple times. | times and for the server to accept the same nonce multiple times. As | |||
As long as the jti value is tracked and duplicates rejected for the | long as the jti value is tracked and duplicates are rejected for the | |||
lifetime of the nonce, there is no additional risk of token replay. | lifetime of the nonce, there is no additional risk of token replay. | |||
11.2. DPoP Proof Pre-Generation | 11.2. DPoP Proof Pre-generation | |||
An attacker in control of the client can pre-generate DPoP proofs for | An attacker in control of the client can pre-generate DPoP proofs for | |||
specific endpoints arbitrarily far into the future by choosing the | specific endpoints arbitrarily far into the future by choosing the | |||
iat value in the DPoP proof to be signed by the proof-of-possession | iat value in the DPoP proof to be signed by the proof-of-possession | |||
key. Note that one such attacker is the person who is the legitimate | key. Note that one such attacker is the person who is the legitimate | |||
user of the client. The user may pre-generate DPoP proofs to | user of the client. The user may pre-generate DPoP proofs to | |||
exfiltrate from the machine possessing the proof-of-possession key | exfiltrate from the machine possessing the proof-of-possession key | |||
upon which they were generated and copy them to another machine that | upon which they were generated and copy them to another machine that | |||
does not possess the key. For instance, a bank employee might pre- | does not possess the key. For instance, a bank employee might pre- | |||
generate DPoP proofs on a bank computer and then copy them to another | generate DPoP proofs on a bank computer and then copy them to another | |||
skipping to change at page 31, line 28 ¶ | skipping to change at line 1399 ¶ | |||
11.3. DPoP Nonce Downgrade | 11.3. DPoP Nonce Downgrade | |||
A server MUST NOT accept any DPoP proofs without the nonce claim when | A server MUST NOT accept any DPoP proofs without the nonce claim when | |||
a DPoP nonce has been provided to the client. | a DPoP nonce has been provided to the client. | |||
11.4. Untrusted Code in the Client Context | 11.4. Untrusted Code in the Client Context | |||
If an adversary is able to run code in the client's execution | If an adversary is able to run code in the client's execution | |||
context, the security of DPoP is no longer guaranteed. Common issues | context, the security of DPoP is no longer guaranteed. Common issues | |||
in web applications leading to the execution of untrusted code are | in web applications leading to the execution of untrusted code are | |||
cross-site scripting and remote code inclusion attacks. | XSS and remote code inclusion attacks. | |||
If the private key used for DPoP is stored in such a way that it | If the private key used for DPoP is stored in such a way that it | |||
cannot be exported, e.g., in a hardware or software security module, | cannot be exported, e.g., in a hardware or software security module, | |||
the adversary cannot exfiltrate the key and use it to create | the adversary cannot exfiltrate the key and use it to create | |||
arbitrary DPoP proofs. The adversary can, however, create new DPoP | arbitrary DPoP proofs. The adversary can, however, create new DPoP | |||
proofs as long as the client is online, and use these proofs | proofs as long as the client is online and uses these proofs | |||
(together with the respective tokens) either on the victim's device | (together with the respective tokens) either on the victim's device | |||
or on a device under the attacker's control to send arbitrary | or on a device under the attacker's control to send arbitrary | |||
requests that will be accepted by servers. | requests that will be accepted by servers. | |||
To send requests even when the client is offline, an adversary can | To send requests even when the client is offline, an adversary can | |||
try to pre-compute DPoP proofs using timestamps in the future and | try to pre-compute DPoP proofs using timestamps in the future and | |||
exfiltrate these together with the access or refresh token. | exfiltrate these together with the access or refresh token. | |||
An adversary might further try to associate tokens issued from the | An adversary might further try to associate tokens issued from the | |||
token endpoint with a key pair under the adversary's control. One | token endpoint with a key pair under the adversary's control. One | |||
skipping to change at page 32, line 20 ¶ | skipping to change at line 1429 ¶ | |||
This grant needs to be "silent", i.e., not require interaction with | This grant needs to be "silent", i.e., not require interaction with | |||
the user. With code running in the client's origin, the adversary | the user. With code running in the client's origin, the adversary | |||
has access to the resulting authorization code and can use it to | has access to the resulting authorization code and can use it to | |||
associate their own DPoP keys with the tokens returned from the token | associate their own DPoP keys with the tokens returned from the token | |||
endpoint. The adversary is then able to use the resulting tokens on | endpoint. The adversary is then able to use the resulting tokens on | |||
their own device even if the client is offline. | their own device even if the client is offline. | |||
Therefore, protecting clients against the execution of untrusted code | Therefore, protecting clients against the execution of untrusted code | |||
is extremely important even if DPoP is used. Besides secure coding | is extremely important even if DPoP is used. Besides secure coding | |||
practices, Content Security Policy [W3C.CSP] can be used as a second | practices, Content Security Policy [W3C.CSP] can be used as a second | |||
layer of defense against cross-site scripting. | layer of defense against XSS. | |||
11.5. Signed JWT Swapping | 11.5. Signed JWT Swapping | |||
Servers accepting signed DPoP proof JWTs MUST verify that the typ | Servers accepting signed DPoP proof JWTs MUST verify that the typ | |||
field is dpop+jwt in the headers of the JWTs to ensure that | field is dpop+jwt in the headers of the JWTs to ensure that | |||
adversaries cannot use JWTs created for other purposes. | adversaries cannot use JWTs created for other purposes. | |||
11.6. Signature Algorithms | 11.6. Signature Algorithms | |||
Implementers MUST ensure that only asymmetric digital signature | Implementers MUST ensure that only asymmetric digital signature | |||
algorithms (such as ES256) that are deemed secure can be used for | algorithms (such as ES256) that are deemed secure can be used for | |||
signing DPoP proofs. In particular, the algorithm none MUST NOT be | signing DPoP proofs. In particular, the algorithm none MUST NOT be | |||
allowed. | allowed. | |||
11.7. Request Integrity | 11.7. Request Integrity | |||
DPoP does not ensure the integrity of the payload or headers of | DPoP does not ensure the integrity of the payload or headers of | |||
requests. The DPoP proof only contains claims for the HTTP URI and | requests. The DPoP proof only contains claims for the HTTP URI and | |||
method, but not, for example, the message body or general request | method, but not the message body or general request headers, for | |||
headers. | example. | |||
This is an intentional design decision intended to keep DPoP simple | This is an intentional design decision intended to keep DPoP simple | |||
to use, but as described, makes DPoP potentially susceptible to | to use, but as described, it makes DPoP potentially susceptible to | |||
replay attacks where an attacker is able to modify message contents | replay attacks where an attacker is able to modify message contents | |||
and headers. In many setups, the message integrity and | and headers. In many setups, the message integrity and | |||
confidentiality provided by TLS is sufficient to provide a good level | confidentiality provided by TLS is sufficient to provide a good level | |||
of protection. | of protection. | |||
Note: While signatures covering other parts of requests are out of | Note: While signatures covering other parts of requests are out of | |||
the scope of this specification, additional information to be signed | the scope of this specification, additional information to be signed | |||
can be added into DPoP proofs. | can be added into DPoP proofs. | |||
11.8. Access Token and Public Key Binding | 11.8. Access Token and Public Key Binding | |||
The binding of the access token to the DPoP public key, which is | The binding of the access token to the DPoP public key, as specified | |||
specified in Section 6, uses a cryptographic hash of the JWK | in Section 6, uses a cryptographic hash of the JWK representation of | |||
representation of the public key. It relies on the hash function | the public key. It relies on the hash function having sufficient | |||
having sufficient second-preimage resistance so as to make it | second-preimage resistance so as to make it computationally | |||
computationally infeasible to find or create another key that | infeasible to find or create another key that produces to the same | |||
produces to the same hash output value. The SHA-256 hash function | hash output value. The SHA-256 hash function was used because it | |||
was used because it meets the aforementioned requirement while being | meets the aforementioned requirement while being widely available. | |||
widely available. | ||||
Similarly, the binding of the DPoP proof to the access token uses a | Similarly, the binding of the DPoP proof to the access token uses a | |||
hash of that access token as the value of the ath claim in the DPoP | hash of that access token as the value of the ath claim in the DPoP | |||
proof (see Section 4.2). This relies on the value of the hash being | proof (see Section 4.2). This relies on the value of the hash being | |||
sufficiently unique so as to reliably identify the access token. The | sufficiently unique so as to reliably identify the access token. The | |||
collision resistance of SHA-256 meets that requirement. | collision resistance of SHA-256 meets that requirement. | |||
11.9. Authorization Code and Public Key Binding | 11.9. Authorization Code and Public Key Binding | |||
Cryptographic binding of the authorization code to the DPoP public | Cryptographic binding of the authorization code to the DPoP public | |||
key, is specified in Section 10. This binding prevents attacks in | key is specified in Section 10. This binding prevents attacks in | |||
which the attacker captures the authorization code and creates a DPoP | which the attacker captures the authorization code and creates a DPoP | |||
proof using a proof-of-possession key other than that held by the | proof using a proof-of-possession key other than the one held by the | |||
client and redeems the authorization code using that DPoP proof. By | client and redeems the authorization code using that DPoP proof. By | |||
ensuring end-to-end that only the client's DPoP key can be used, this | ensuring end to end that only the client's DPoP key can be used, this | |||
prevents captured authorization codes from being exfiltrated and used | prevents captured authorization codes from being exfiltrated and used | |||
at locations other than the one to which the authorization code was | at locations other than the one to which the authorization code was | |||
issued. | issued. | |||
Authorization codes can, for instance, be harvested by attackers from | Authorization codes can, for instance, be harvested by attackers from | |||
places that the HTTP messages containing them are logged. Even when | places where the HTTP messages containing them are logged. Even when | |||
efforts are made to make authorization codes one-time-use, in | efforts are made to make authorization codes one-time-use, in | |||
practice, there is often a time window during which attackers can | practice, there is often a time window during which attackers can | |||
replay them. For instance, when authorization servers are | replay them. For instance, when authorization servers are | |||
implemented as scalable replicated services, some replicas may | implemented as scalable replicated services, some replicas may | |||
temporarily not yet have the information needed to prevent replay. | temporarily not yet have the information needed to prevent replay. | |||
DPoP binding of the authorization code solves these problems. | DPoP binding of the authorization code solves these problems. | |||
If an authorization server does not (or cannot) strictly enforce the | If an authorization server does not (or cannot) strictly enforce the | |||
single-use limitation for authorization codes and an attacker can | single-use limitation for authorization codes and an attacker can | |||
access the authorization code (and if PKCE is used, the | access the authorization code (and if PKCE is used, the | |||
code_verifier), the attacker can create a forged token request, | code_verifier), the attacker can create a forged token request, | |||
binding the resulting token to an attacker-controlled key. For | binding the resulting token to an attacker-controlled key. For | |||
example, using cross-site scripting, attackers might obtain access to | example, using XSS, attackers might obtain access to the | |||
the authorization code and PKCE parameters. Use of the dpop_jkt | authorization code and PKCE parameters. Use of the dpop_jkt | |||
parameter prevents this attack. | parameter prevents this attack. | |||
The binding of the authorization code to the DPoP public key uses a | The binding of the authorization code to the DPoP public key uses a | |||
JWK Thumbprint of the public key, just as the access token binding | JWK Thumbprint of the public key, just as the access token binding | |||
does. The same JWK Thumbprint considerations apply. | does. The same JWK Thumbprint considerations apply. | |||
11.10. Hash Algorithm Agility | 11.10. Hash Algorithm Agility | |||
The jkt confirmation method member, the ath JWT claim, and the | The jkt confirmation method member, the ath JWT claim, and the | |||
dpop_jkt authorization request parameter defined herein all use the | dpop_jkt authorization request parameter defined herein all use the | |||
output of the SHA-256 hash function as their value. The use of a | output of the SHA-256 hash function as their value. The use of a | |||
single hash function by this specification was intentional and aimed | single hash function by this specification was intentional and aimed | |||
at simplicity and avoidance of potential security and | at simplicity and avoidance of potential security and | |||
interoperability issues arising from common mistakes implementing and | interoperability issues arising from common mistakes implementing and | |||
deploying parameterized algorithm agility schemes. The use of a | deploying parameterized algorithm agility schemes. However, the use | |||
different hash function is not precluded, however, if future | of a different hash function is not precluded if future circumstances | |||
circumstances change making SHA-256 insufficient for the requirements | change and make SHA-256 insufficient for the requirements of this | |||
of this specification. Should that need arise, it is expected that a | specification. Should that need arise, it is expected that a short | |||
short specification be produced that updates this one. That | specification will be produced that updates this one. Using the | |||
specification will likely define, using the output of a then | output of an appropriate hash function as the value, that | |||
appropriate hash function as the value, a new confirmation method | specification will likely define a new confirmation method member, a | |||
member, a new JWT claim, and a new authorization request parameter. | new JWT claim, and a new authorization request parameter. These | |||
These items will be used in place of, or alongside, their respective | items will be used in place of, or alongside, their respective | |||
counterparts in the same message structures and flows of the larger | counterparts in the same message structures and flows of the larger | |||
protocol defined by this specification. | protocol defined by this specification. | |||
11.11. Binding to Client Identity | 11.11. Binding to Client Identity | |||
In cases where DPoP is used with client authentication, it is only | In cases where DPoP is used with client authentication, it is only | |||
bound to authentication by being coincident in the same TLS tunnel. | bound to authentication by being coincident in the same TLS tunnel. | |||
Since the DPoP proof is not directly cryptographically bound to the | Since the DPoP proof is not directly bound to the authentication | |||
authentication, it's possible that the authentication or the DPoP | cryptographically, it's possible that the authentication or the DPoP | |||
messages were copied into the tunnel. While including the URI in the | messages were copied into the tunnel. While including the URI in the | |||
DPoP can partially mitigate some of this risk, modifying the | DPoP can partially mitigate some of this risk, modifying the | |||
authentication mechanism to provide cryptographic binding between | authentication mechanism to provide cryptographic binding between | |||
authentication and DPoP could provide better protection. However, | authentication and DPoP could provide better protection. However, | |||
providing additional binding with authentication through the | providing additional binding with authentication through the | |||
modification of authentication mechanisms or other means is beyond | modification of authentication mechanisms or other means is beyond | |||
the scope of this specification. | the scope of this specification. | |||
12. IANA Considerations | 12. IANA Considerations | |||
12.1. OAuth Access Token Type Registration | 12.1. OAuth Access Token Types Registration | |||
This specification requests registration of the following access | IANA has registered the following access token type in the "OAuth | |||
token type in the "OAuth Access Token Types" registry | Access Token Types" registry [IANA.OAuth.Params] established by | |||
[IANA.OAuth.Params] established by [RFC6749]. | [RFC6749]. | |||
* Type name: DPoP | Name: DPoP | |||
* Additional Token Endpoint Response Parameters: (none) | ||||
* HTTP Authentication Scheme(s): DPoP | Additional Token Endpoint Response Parameters: (none) | |||
* Change controller: IETF | ||||
* Specification document(s): [[ this specification ]] | HTTP Authentication Scheme(s): DPoP | |||
Change Controller: IETF | ||||
Reference: RFC 9449 | ||||
12.2. OAuth Extensions Error Registration | 12.2. OAuth Extensions Error Registration | |||
This specification requests registration of the following error | IANA has registered the following error values in the "OAuth | |||
values in the "OAuth Extensions Error" registry [IANA.OAuth.Params] | Extensions Error" registry [IANA.OAuth.Params] established by | |||
established by [RFC6749]. | [RFC6749]. | |||
Invalid DPoP proof: | Invalid DPoP proof: | |||
* Name: invalid_dpop_proof | Name: invalid_dpop_proof | |||
* Usage Location: token error response, resource access error | ||||
response | Usage Location: token error response, resource access error | |||
* Protocol Extension: Demonstrating Proof of Possession (DPoP) | response | |||
* Change controller: IETF | ||||
* Specification document(s): [[ this specification ]] | Protocol Extension: Demonstrating Proof of Possession (DPoP) | |||
Change Controller: IETF | ||||
Reference: RFC 9449 | ||||
Use DPoP nonce: | Use DPoP nonce: | |||
* Name: use_dpop_nonce | Name: use_dpop_nonce | |||
* Usage Location: token error response, resource access error | ||||
response | Usage Location: token error response, resource access error | |||
* Protocol Extension: Demonstrating Proof of Possession (DPoP) | response | |||
* Change controller: IETF | ||||
* Specification document(s): [[ this specification ]] | Protocol Extension: Demonstrating Proof of Possession (DPoP) | |||
Change Controller: IETF | ||||
Reference: RFC 9449 | ||||
12.3. OAuth Parameters Registration | 12.3. OAuth Parameters Registration | |||
This specification requests registration of the following | IANA has registered the following authorization request parameter in | |||
authorization request parameter in the "OAuth Parameters" registry | the "OAuth Parameters" registry [IANA.OAuth.Params] established by | |||
[IANA.OAuth.Params] established by [RFC6749]. | [RFC6749]. | |||
* Name: dpop_jkt | Name: dpop_jkt | |||
* Parameter Usage Location: authorization request | ||||
* Change Controller: IETF | ||||
* Reference: [[ Section 10 of this specification ]] | ||||
12.4. HTTP Authentication Scheme Registration | Parameter Usage Location: authorization request | |||
This specification requests registration of the following scheme in | Change Controller: IETF | |||
the "Hypertext Transfer Protocol (HTTP) Authentication Scheme | ||||
Registry" [RFC9110][IANA.HTTP.AuthSchemes]: | ||||
* Authentication Scheme Name: DPoP | Reference: Section 10 of RFC 9449 | |||
* Reference: [[ Section 7.1 of this specification ]] | ||||
12.4. HTTP Authentication Schemes Registration | ||||
IANA has registered the following scheme in the "HTTP Authentication | ||||
Schemes" registry [IANA.HTTP.AuthSchemes] established by [RFC9110], | ||||
Section 16.4.1. | ||||
Authentication Scheme Name: DPoP | ||||
Reference: Section 7.1 of RFC 9449 | ||||
12.5. Media Type Registration | 12.5. Media Type Registration | |||
This section registers the application/dpop+jwt media type [RFC2046] | IANA has registered the application/dpop+jwt media type [RFC2046] in | |||
in the IANA "Media Types" registry [IANA.MediaTypes] in the manner | the "Media Types" registry [IANA.MediaTypes] in the manner described | |||
described in [RFC6838], which is used to indicate that the content is | in [RFC6838], which is used to indicate that the content is a DPoP | |||
a DPoP JWT. | JWT. | |||
* Type name: application | Type name: application | |||
* Subtype name: dpop+jwt | ||||
* Required parameters: n/a | Subtype name: dpop+jwt | |||
* Optional parameters: n/a | ||||
* Encoding considerations: binary; A DPoP JWT is a JWT; JWT values | Required parameters: n/a | |||
Optional parameters: n/a | ||||
Encoding considerations: binary. A DPoP JWT is a JWT; JWT values | ||||
are encoded as a series of base64url-encoded values (some of which | are encoded as a series of base64url-encoded values (some of which | |||
may be the empty string) separated by period ('.') characters. | may be the empty string) separated by period ('.') characters. | |||
* Security considerations: See Section 11 of [[ this specification | ||||
]] | Security considerations: See Section 11 of RFC 9449 | |||
* Interoperability considerations: n/a | ||||
* Published specification: [[ this specification ]] | Interoperability considerations: n/a | |||
* Applications that use this media type: Applications using [[ this | ||||
specification ]] for application-level proof of possession | Published specification: RFC 9449 | |||
* Fragment identifier considerations: n/a | ||||
* Additional information: | Applications that use this media type: Applications using RFC 9449 | |||
- File extension(s): n/a | for application-level proof of possession | |||
- Macintosh file type code(s): n/a | ||||
* Person & email address to contact for further information: Michael | Fragment identifier considerations: n/a | |||
B. Jones, mbj@microsoft.com | ||||
* Intended usage: COMMON | Additional information: | |||
* Restrictions on usage: none | ||||
* Author: Michael B. Jones, mbj@microsoft.com | File extension(s): n/a | |||
* Change controller: IETF | Macintosh file type code(s): n/a | |||
* Provisional registration? No | ||||
Person & email address to contact for further information: Michael | ||||
B. Jones, michael_b_jones@hotmail.com | ||||
Intended usage: COMMON | ||||
Restrictions on usage: none | ||||
Author: Michael B. Jones, michael_b_jones@hotmail.com | ||||
Change controller: IETF | ||||
12.6. JWT Confirmation Methods Registration | 12.6. JWT Confirmation Methods Registration | |||
This specification requests registration of the following value in | IANA has registered the following JWT cnf member value in the "JWT | |||
the IANA "JWT Confirmation Methods" registry [IANA.JWT] for JWT cnf | Confirmation Methods" registry [IANA.JWT] established by [RFC7800]. | |||
member values established by [RFC7800]. | ||||
* Confirmation Method Value: jkt | Confirmation Method Value: jkt | |||
* Confirmation Method Description: JWK SHA-256 Thumbprint | ||||
* Change Controller: IETF | Confirmation Method Description: JWK SHA-256 Thumbprint | |||
* Specification Document(s): [[ Section 6 of this specification ]] | ||||
Change Controller: IETF | ||||
Reference: Section 6 of RFC 9449 | ||||
12.7. JSON Web Token Claims Registration | 12.7. JSON Web Token Claims Registration | |||
This specification requests registration of the following Claims in | IANA has registered the following Claims in the "JSON Web Token | |||
the IANA "JSON Web Token Claims" registry [IANA.JWT] established by | Claims" registry [IANA.JWT] established by [RFC7519]. | |||
[RFC7519]. | ||||
HTTP method: | HTTP method: | |||
* Claim Name: htm | Claim Name: htm | |||
* Claim Description: The HTTP method of the request | ||||
* Change Controller: IETF | Claim Description: The HTTP method of the request | |||
* Specification Document(s): [[ Section 4.2 of this specification ]] | ||||
Change Controller: IETF | ||||
Reference: Section 4.2 of RFC 9449 | ||||
HTTP URI: | HTTP URI: | |||
* Claim Name: htu | Claim Name: htu | |||
* Claim Description: The HTTP URI of the request (without query and | ||||
fragment parts) | Claim Description: The HTTP URI of the request (without query and | |||
* Change Controller: IETF | fragment parts) | |||
* Specification Document(s): [[ Section 4.2 of this specification ]] | ||||
Change Controller: IETF | ||||
Reference: Section 4.2 of RFC 9449 | ||||
Access token hash: | Access token hash: | |||
* Claim Name: ath | Claim Name: ath | |||
* Claim Description: The base64url encoded SHA-256 hash of the ASCII | ||||
encoding of the associated access token's value | ||||
* Change Controller: IETF | ||||
* Specification Document(s): [[ Section 4.2 of this specification ]] | ||||
12.7.1. "nonce" Registry Update | Claim Description: The base64url-encoded SHA-256 hash of the | |||
ASCII encoding of the associated access token's value | ||||
Change Controller: IETF | ||||
Reference: Section 4.2 of RFC 9449 | ||||
12.7.1. "nonce" Registration Update | ||||
The Internet Security Glossary [RFC4949] provides a useful definition | The Internet Security Glossary [RFC4949] provides a useful definition | |||
of nonce as a random or non-repeating value that is included in data | of nonce as a random or non-repeating value that is included in data | |||
exchanged by a protocol, usually for the purpose of guaranteeing | exchanged by a protocol, usually for the purpose of guaranteeing | |||
liveness and thus detecting and protecting against replay attacks. | liveness and thus detecting and protecting against replay attacks. | |||
However, the initial registration of the nonce claim by [OpenID.Core] | However, the initial registration of the nonce claim by [OpenID.Core] | |||
used language that was contextually specific to that application, | used language that was contextually specific to that application, | |||
which was potentially limiting to its general applicability. | which was potentially limiting to its general applicability. | |||
This specification therefore requests that the entry for nonce in the | Therefore, IANA has updated the entry for nonce in the "JSON Web | |||
IANA "JSON Web Token Claims" registry [IANA.JWT] be updated as | Token Claims" registry [IANA.JWT] with an expanded definition to | |||
follows to reflect that the claim can be used appropriately in other | reflect that the claim can be used appropriately in other contexts | |||
contexts. | and with the addition of this document as a reference, as follows. | |||
* Claim Name: nonce | Claim Name: nonce | |||
* Claim Description: Value used to associate a Client session with | ||||
an ID Token (MAY also be used for nonce values in other | ||||
applications of JWTs) | ||||
* Change Controller: OpenID Foundation Artifact Binding Working | ||||
Group - openid-specs-ab@lists.openid.net | ||||
* Specification Document(s): Section 2 of [OpenID.Core] and [[ this | ||||
specification ]] | ||||
12.8. HTTP Message Header Field Names Registration | Claim Description: Value used to associate a Client session with an | |||
ID Token (MAY also be used for nonce values in other applications | ||||
of JWTs) | ||||
This document specifies the following HTTP header fields, | Change Controller: OpenID Foundation Artifact Binding Working Group, | |||
registration of which is requested in the "Hypertext Transfer | openid-specs-ab@lists.openid.net | |||
Protocol (HTTP) Field Name Registry" registry | ||||
[RFC9110][IANA.HTTP.Fields]: | ||||
* Field name: DPoP | Specification Document(s): Section 2 of [OpenID.Core] and RFC 9449 | |||
* Status: permanent | 12.8. Hypertext Transfer Protocol (HTTP) Field Name Registration | |||
* Specification document: [[ this specification ]] | IANA has registered the following HTTP header fields, as specified by | |||
this document, in the "Hypertext Transfer Protocol (HTTP) Field Name | ||||
Registry" [IANA.HTTP.Fields] established by [RFC9110]: | ||||
* Field name: DPoP-Nonce | DPoP: | |||
* Status: permanent | Field Name: DPoP | |||
* Specification document: [[ this specification ]] | Status: permanent | |||
Reference: RFC 9449 | ||||
DPoP-Nonce: | ||||
Field Name: DPoP-Nonce | ||||
Status: permanent | ||||
Reference: RFC 9449 | ||||
12.9. OAuth Authorization Server Metadata Registration | 12.9. OAuth Authorization Server Metadata Registration | |||
This specification requests registration of the following value in | IANA has registered the following value in the "OAuth Authorization | |||
the IANA "OAuth Authorization Server Metadata" registry | Server Metadata" registry [IANA.OAuth.Params] established by | |||
[IANA.OAuth.Params] established by [RFC8414]. | [RFC8414]. | |||
* Metadata Name: dpop_signing_alg_values_supported | Metadata Name: dpop_signing_alg_values_supported | |||
* Metadata Description: JSON array containing a list of the JWS | ||||
Metadata Description: JSON array containing a list of the JWS | ||||
algorithms supported for DPoP proof JWTs | algorithms supported for DPoP proof JWTs | |||
* Change Controller: IETF | ||||
* Specification Document(s): [[ Section 5.1 of this specification ]] | Change Controller: IETF | |||
Reference: Section 5.1 of RFC 9449 | ||||
12.10. OAuth Dynamic Client Registration Metadata | 12.10. OAuth Dynamic Client Registration Metadata | |||
This specification requests registration of the following value in | IANA has registered the following value in the IANA "OAuth Dynamic | |||
the IANA "OAuth Dynamic Client Registration Metadata" registry | Client Registration Metadata" registry [IANA.OAuth.Params] | |||
[IANA.OAuth.Params] established by [RFC7591]. | established by [RFC7591]. | |||
* Metadata Name: dpop_bound_access_tokens | Client Metadata Name: dpop_bound_access_tokens | |||
* Metadata Description: Boolean value specifying whether the client | ||||
always uses DPoP for token requests | ||||
* Change Controller: IETF | ||||
* Specification Document(s): [[ Section 5.2 of this specification ]] | ||||
13. Normative References | Client Metadata Description: Boolean value specifying whether the | |||
client always uses DPoP for token requests | ||||
Change Controller: IETF | ||||
Reference: Section 5.2 of RFC 9449 | ||||
13. References | ||||
13.1. Normative References | ||||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
<https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | |||
Resource Identifier (URI): Generic Syntax", STD 66, | Resource Identifier (URI): Generic Syntax", STD 66, | |||
RFC 3986, DOI 10.17487/RFC3986, January 2005, | RFC 3986, DOI 10.17487/RFC3986, January 2005, | |||
<https://www.rfc-editor.org/info/rfc3986>. | <https://www.rfc-editor.org/info/rfc3986>. | |||
skipping to change at page 40, line 15 ¶ | skipping to change at line 1856 ¶ | |||
[RFC7800] Jones, M., Bradley, J., and H. Tschofenig, "Proof-of- | [RFC7800] Jones, M., Bradley, J., and H. Tschofenig, "Proof-of- | |||
Possession Key Semantics for JSON Web Tokens (JWTs)", | Possession Key Semantics for JSON Web Tokens (JWTs)", | |||
RFC 7800, DOI 10.17487/RFC7800, April 2016, | RFC 7800, DOI 10.17487/RFC7800, April 2016, | |||
<https://www.rfc-editor.org/info/rfc7800>. | <https://www.rfc-editor.org/info/rfc7800>. | |||
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
[SHS] National Institute of Standards and Technology, "Secure | [SHS] National Institute of Standards and Technology, "Secure | |||
Hash Standard (SHS)", FIPS PUB 180-4, August 2015, | Hash Standard (SHS)", FIPS PUB 180-4, | |||
<https://nvlpubs.nist.gov/nistpubs/FIPS/ | DOI 10.6028/NIST.FIPS.180-4, August 2015, | |||
NIST.FIPS.180-4.pdf>. | <http://dx.doi.org/10.6028/NIST.FIPS.180-4>. | |||
14. Informative References | 13.2. Informative References | |||
[BREACH] "CVE-2013-3587", <https://cve.mitre.org/cgi-bin/ | [BREACH] CVE, "CVE-2013-3587", <https://cve.mitre.org/cgi-bin/ | |||
cvename.cgi?name=CVE-2013-3587>. | cvename.cgi?name=CVE-2013-3587>. | |||
[CRIME] "CVE-2012-4929", <https://cve.mitre.org/cgi-bin/ | ||||
cvename.cgi?name=cve-2012-4929>. | ||||
[Cloudbleed] | [Cloudbleed] | |||
"Incident report on memory leak caused by Cloudflare | Graham-Cumming, J., "Incident report on memory leak caused | |||
parser bug", <https://blog.cloudflare.com/incident-report- | by Cloudflare parser bug", February 2017, | |||
on-memory-leak-caused-by-cloudflare-parser-bug/>. | <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] | [GitHub.Tokens] | |||
"Security alert: Attack campaign involving stolen OAuth | Hanley, M., "Security alert: Attack campaign involving | |||
user tokens issued to two third-party integrators", | stolen OAuth user tokens issued to two third-party | |||
<https://github.blog/2022-04-15-security-alert-stolen- | integrators", April 2022, <https://github.blog/2022-04-15- | |||
oauth-user-tokens/>. | security-alert-stolen-oauth-user-tokens/>. | |||
[Heartbleed] | [Heartbleed] | |||
"CVE-2014-0160", <https://cve.mitre.org/cgi-bin/ | "CVE-2014-0160", <https://cve.mitre.org/cgi-bin/ | |||
cvename.cgi?name=cve-2014-0160>. | cvename.cgi?name=cve-2014-0160>. | |||
[I-D.ietf-oauth-security-topics] | ||||
Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, | ||||
"OAuth 2.0 Security Best Current Practice", Work in | ||||
Progress, Internet-Draft, draft-ietf-oauth-security- | ||||
topics-22, 13 March 2023, | ||||
<https://datatracker.ietf.org/doc/html/draft-ietf-oauth- | ||||
security-topics-22>. | ||||
[I-D.ietf-oauth-token-binding] | ||||
Jones, M., Campbell, B., Bradley, J., and W. Denniss, | ||||
"OAuth 2.0 Token Binding", Work in Progress, Internet- | ||||
Draft, draft-ietf-oauth-token-binding-08, 19 October 2018, | ||||
<https://datatracker.ietf.org/doc/html/draft-ietf-oauth- | ||||
token-binding-08>. | ||||
[IANA.HTTP.AuthSchemes] | [IANA.HTTP.AuthSchemes] | |||
IANA, "Hypertext Transfer Protocol (HTTP) Authentication | IANA, "Hypertext Transfer Protocol (HTTP) Authentication | |||
Scheme Registry", | Scheme Registry", | |||
<https://www.iana.org/assignments/http-authschemes>. | <https://www.iana.org/assignments/http-authschemes/>. | |||
[IANA.HTTP.Fields] | [IANA.HTTP.Fields] | |||
IANA, "Hypertext Transfer Protocol (HTTP) Field Name | IANA, "Hypertext Transfer Protocol (HTTP) Field Name | |||
Registry", <https://www.iana.org/assignments/http-fields/ | Registry", | |||
http-fields.xhtml>. | <https://www.iana.org/assignments/http-fields/>. | |||
[IANA.JOSE.ALGS] | [IANA.JOSE.ALGS] | |||
IANA, "JSON Web Signature and Encryption Algorithms", | IANA, "JSON Web Signature and Encryption Algorithms", | |||
<https://www.iana.org/assignments/jose/jose.xhtml#web- | <https://www.iana.org/assignments/jose/>. | |||
signature-encryption-algorithms>. | ||||
[IANA.JWT] IANA, "JSON Web Token Claims", | [IANA.JWT] IANA, "JSON Web Token Claims", | |||
<https://www.iana.org/assignments/jwt>. | <https://www.iana.org/assignments/jwt/>. | |||
[IANA.MediaTypes] | [IANA.MediaTypes] | |||
IANA, "Media Types", | IANA, "Media Types", | |||
<https://www.iana.org/assignments/media-types>. | <https://www.iana.org/assignments/media-types/>. | |||
[IANA.OAuth.Params] | [IANA.OAuth.Params] | |||
IANA, "OAuth Parameters", | IANA, "OAuth Parameters", | |||
<https://www.iana.org/assignments/oauth-parameters>. | <https://www.iana.org/assignments/oauth-parameters/>. | |||
[OpenID.Core] | [OpenID.Core] | |||
Sakimura, N., Bradley, J., Jones, M.B., Medeiros, B.d., | Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and | |||
and C. Mortimore, "OpenID Connect Core 1.0", November | C. Mortimore, "OpenID Connect Core 1.0 incorporating | |||
2014, | errata set 1", November 2014, | |||
<https://openid.net/specs/openid-connect-core-1_0.html>. | <https://openid.net/specs/openid-connect-core-1_0.html>. | |||
[RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail | [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail | |||
Extensions (MIME) Part Two: Media Types", RFC 2046, | Extensions (MIME) Part Two: Media Types", RFC 2046, | |||
DOI 10.17487/RFC2046, November 1996, | DOI 10.17487/RFC2046, November 1996, | |||
<https://www.rfc-editor.org/info/rfc2046>. | <https://www.rfc-editor.org/info/rfc2046>. | |||
[RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally | [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally | |||
Unique IDentifier (UUID) URN Namespace", RFC 4122, | Unique IDentifier (UUID) URN Namespace", RFC 4122, | |||
DOI 10.17487/RFC4122, July 2005, | DOI 10.17487/RFC4122, July 2005, | |||
skipping to change at page 43, line 20 ¶ | skipping to change at line 1988 ¶ | |||
[RFC9110] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | [RFC9110] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | |||
Ed., "HTTP Semantics", STD 97, RFC 9110, | Ed., "HTTP Semantics", STD 97, RFC 9110, | |||
DOI 10.17487/RFC9110, June 2022, | DOI 10.17487/RFC9110, June 2022, | |||
<https://www.rfc-editor.org/info/rfc9110>. | <https://www.rfc-editor.org/info/rfc9110>. | |||
[RFC9126] Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D., | [RFC9126] Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D., | |||
and F. Skokan, "OAuth 2.0 Pushed Authorization Requests", | and F. Skokan, "OAuth 2.0 Pushed Authorization Requests", | |||
RFC 9126, DOI 10.17487/RFC9126, September 2021, | RFC 9126, DOI 10.17487/RFC9126, September 2021, | |||
<https://www.rfc-editor.org/info/rfc9126>. | <https://www.rfc-editor.org/info/rfc9126>. | |||
[W3C.CSP] West, M., "Content Security Policy Level 3", World Wide | [SECURITY-TOPICS] | |||
Web Consortium Working Draft WD-CSP3-20181015, 15 October | Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, | |||
2018, <https://www.w3.org/TR/2018/WD-CSP3-20181015/>. | "OAuth 2.0 Security Best Current Practice", Work in | |||
Progress, Internet-Draft, draft-ietf-oauth-security- | ||||
topics-23, 5 June 2023, | ||||
<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 Token Binding", Work in Progress, Internet- | ||||
Draft, draft-ietf-oauth-token-binding-08, 19 October 2018, | ||||
<https://datatracker.ietf.org/doc/html/draft-ietf-oauth- | ||||
token-binding-08>. | ||||
[W3C.CSP] West, M., "Content Security Policy Level 3", W3C Working | ||||
Draft, July 2023, <https://www.w3.org/TR/CSP3/>. | ||||
[W3C.WebCryptoAPI] | [W3C.WebCryptoAPI] | |||
Watson, M., "Web Cryptography API", World Wide Web | Watson, M., "Web Cryptography API", W3C Recommendation, | |||
Consortium Recommendation REC-WebCryptoAPI-20170126, 26 | ||||
January 2017, | January 2017, | |||
<https://www.w3.org/TR/2017/REC-WebCryptoAPI-20170126>. | <https://www.w3.org/TR/2017/REC-WebCryptoAPI-20170126>. | |||
[WHATWG.Fetch] | [WHATWG.Fetch] | |||
WHATWG, "Fetch Living Standard", May 2022, | WHATWG, "Fetch Living Standard", July 2023, | |||
<https://fetch.spec.whatwg.org/>. | <https://fetch.spec.whatwg.org/>. | |||
Appendix A. Acknowledgements | Acknowledgements | |||
We would like to thank Brock Allen, Annabelle Backman, Spencer | We would like to thank Brock Allen, Annabelle Backman, Dominick | |||
Balogh, Dominick Baier, Vittorio Bertocci, Jeff Corrigan, Domingos | Baier, Spencer Balogh, Vittorio Bertocci, Jeff Corrigan, Domingos | |||
Creado, Andrii Deinega, William Denniss, Vladimir Dzhuvinov, Mike | Creado, Philippe De Ryck, Andrii Deinega, William Denniss, Vladimir | |||
Engan, Nikos Fotiou, Mark Haine, Dick Hardt, Joseph Heenan, Bjorn | Dzhuvinov, Mike Engan, Nikos Fotiou, Mark Haine, Dick Hardt, Joseph | |||
Hjelm, Jacob Ideskog, Jared Jennings, Benjamin Kaduk, Pieter | Heenan, Bjorn Hjelm, Jacob Ideskog, Jared Jennings, Benjamin Kaduk, | |||
Kasselman, Neil Madden, Rohan Mahy, Karsten Meyer zu Selhausen, | Pieter Kasselman, Neil Madden, Rohan Mahy, Karsten Meyer zu | |||
Nicolas Mora, Steinar Noem, Mark Nottingham, Rob Otto, Aaron Parecki, | Selhausen, Nicolas Mora, Steinar Noem, Mark Nottingham, Rob Otto, | |||
Michael Peck, Roberto Polli, Paul Querna, Justin Richer, Joseph | Aaron Parecki, Michael Peck, Roberto Polli, Paul Querna, Justin | |||
Salowey, Rifaat Shekh-Yusef, Filip Skokan, Dmitry Telegin, Dave | Richer, Joseph Salowey, Rifaat Shekh-Yusef, Filip Skokan, Dmitry | |||
Tonge, Jim Willeke, Philippe De Ryck, and others (please let us know, | Telegin, Dave Tonge, Jim Willeke, and others for their valuable | |||
if you've been mistakenly omitted) for their valuable input, feedback | input, feedback, and general support of this work. | |||
and general support of this work. | ||||
This document originated from discussions at the 4th OAuth Security | This document originated from discussions at the 4th OAuth Security | |||
Workshop in Stuttgart, Germany. We thank the organizers of this | Workshop in Stuttgart, Germany. We thank the organizers of this | |||
workshop (Ralf Kusters, Guido Schmitz). | workshop (Ralf Küsters and Guido Schmitz). | |||
Appendix B. Document History | ||||
[[ To be removed from the final specification ]] | ||||
-16 | ||||
* Per suggestion of the registry's designated expert, change | ||||
"resource error response" to "resource access error response" for | ||||
location of the two items in the "OAuth Extensions Error | ||||
Registration" section | ||||
-15 | ||||
* Editorial updates from IESG review/ballot | ||||
* Mike Jones and Daniel Fett with new email/organization info | ||||
-14 | ||||
* Add sec considerations sub-section about binding to client | ||||
identity | ||||
* Explicitly say that nonces must be unpredictable | ||||
* Change to a numbered list in 'Checking DPoP Proofs' | ||||
* Editorial adjustments | ||||
* Incorporated HTTP header field definition and RFC 8792 '\' line | ||||
wrapping suggestions by Mark Nottingham | ||||
-13 | ||||
* Editorial updates/fixes | ||||
* Make sure RFC7519 is a normative reference | ||||
-12 | ||||
* Updates from Roman Danyliw's AD review | ||||
* DPoP-Nonce now included in HTTP header field registration request | ||||
* Fixed section reference to URI Scheme-Based Normalization | ||||
* Attempt to better describe the rationale for SHA-256 only and | ||||
expectations for how hash algorithm agility would be achieved if | ||||
needed in the future | ||||
* Elaborate on the use of multiple WWW-Authenticate challenges by | ||||
protected resources | ||||
* Fix access token request examples that were missing a client_id | ||||
-11 | ||||
* Updates addressing outstanding shepherd review comments per side | ||||
meeting discussions at IETF 114 | ||||
* Added more explanation of the PAR considerations | ||||
* Added parenthetical remark "(such as ES256)" to Signature | ||||
Algorithms subsection | ||||
* Added more explanation for ath | ||||
* Added a reference to RFC8725 in mention of explicit JWT typing | ||||
-10 | ||||
* Updates addressing some shepherd review comments | ||||
* Update HTTP references as RFCs 723x have been superseded by RFC | ||||
9110 | ||||
* Editorial fixes | ||||
* Added some clarifications, etc. around nonce | ||||
* Added client considerations subsection | ||||
* Use bullets rather than numbers in Checking DPoP Proofs so as not | ||||
to imply specific order | ||||
* Added notes/reminders about browser-based client applications | ||||
using CORS needing access to response headers | ||||
* Added a JWT claims registry update request for "nonce" to (better) | ||||
allow for more general use in other contexts | ||||
-09 | ||||
* Add note/reminder about browser-based client applications using | ||||
CORS needing access to response headers. | ||||
* Fixed typo | ||||
-08 | ||||
* Lots of editorial updates from WGLC feedback | ||||
* Further clarify that either iat or nonce can be used alone in | ||||
validating the timeliness of the proof and somewhat de-emphasize | ||||
jti tracking | ||||
-07 | ||||
* Registered the application/dpop+jwt media type. | ||||
* Editorial updates/clarifications based on review feedback. | ||||
* Added "(on the order of seconds or minutes)" to somewhat qualify | ||||
"relatively brief period" and "reasonably near future" and give a | ||||
general idea of expected timeframe without being overly | ||||
prescriptive. | ||||
* Added a step to Section 4.3 to reiterate that the jwk header | ||||
cannot have a private key. | ||||
-06 | ||||
* Editorial updates and fixes | ||||
* Changed name of client metadata parameter to | ||||
dpop_bound_access_tokens | ||||
-05 | ||||
* Added Authorization Code binding via the dpop_jkt parameter. | ||||
* Described the authorization code reuse attack and how dpop_jkt | ||||
mitigates it. | ||||
* Enhanced description of DPoP proof expiration checking. | ||||
* Described nonce storage requirements and how nonce mismatches and | ||||
missing nonces are self-correcting. | ||||
* Specified the use of the use_dpop_nonce error for missing and | ||||
mismatched nonce values. | ||||
* Specified that authorization servers use 400 (Bad Request) errors | ||||
to supply nonces and resource servers use 401 (Unauthorized) | ||||
errors to do so. | ||||
* Added a bit more about ath and pre-generated proofs to the | ||||
security considerations. | ||||
* Mentioned confirming the DPoP binding of the access token in the | ||||
list in Section 4.3. | ||||
* Added the always_uses_dpop client registration metadata parameter. | ||||
* Described the relationship between DPoP and Pushed Authorization | ||||
Requests (PAR). | ||||
* Updated references for drafts that are now RFCs. | ||||
-04 | ||||
* Added the option for a server-provided nonce in the DPoP proof. | ||||
* Registered the invalid_dpop_proof and use_dpop_nonce error codes. | ||||
* Removed fictitious uses of realm from the examples, as they added | ||||
no value. | ||||
* State that if the introspection response has a token_type, it has | ||||
to be DPoP. | ||||
* Mention that RFC7235 allows multiple authentication schemes in | ||||
WWW-Authenticate with a 401. | ||||
* Editorial fixes. | ||||
-03 | ||||
* Add an access token hash (ath) claim to the DPoP proof when used | ||||
in conjunction with the presentation of an access token for | ||||
protected resource access | ||||
* add Untrusted Code in the Client Context section to security | ||||
considerations | ||||
* Editorial updates and fixes | ||||
-02 | ||||
* Lots of editorial updates and additions including expanding on the | ||||
objectives, better defining the key confirmation representations, | ||||
example updates and additions, better describing mixed bearer/dpop | ||||
token type deployments, clarify RT binding only being done for | ||||
public clients and why, more clearly allow for a bound RT but with | ||||
bearer AT, explain/justify the choice of SHA-256 for key binding, | ||||
and more | ||||
* Require that a protected resource supporting bearer and DPoP at | ||||
the same time must reject an access token received as bearer, if | ||||
that token is DPoP-bound | ||||
* Remove the case-insensitive qualification on the htm claim check | ||||
* Relax the jti tracking requirements a bit and qualify it by URI | ||||
-01 | ||||
* Editorial updates | ||||
* Attempt to more formally define the DPoP Authorization header | ||||
scheme | ||||
* Define the 401/WWW-Authenticate challenge | ||||
* Added invalid_dpop_proof error code for DPoP errors in token | ||||
request | ||||
* Fixed up and added to the IANA section | ||||
* Added dpop_signing_alg_values_supported authorization server | ||||
metadata | ||||
* Moved the Acknowledgements into an Appendix and added a bunch of | ||||
names (best effort) | ||||
-00 [[ Working Group Draft ]] | ||||
* Working group draft | ||||
-04 | ||||
* Update OAuth MTLS reference to RFC 8705 | ||||
* Use the newish RFC v3 XML and HTML format | ||||
-03 | ||||
* rework the text around uniqueness requirements on the jti claim in | ||||
the DPoP proof JWT | ||||
* make tokens a bit smaller by using htm, htu, and jkt rather than | ||||
http_method, http_uri, and jkt#S256 respectively | ||||
* more explicit recommendation to use mTLS if that is available | ||||
* added David Waite as co-author | ||||
* editorial updates | ||||
-02 | ||||
* added normalization rules for URIs | ||||
* removed distinction between proof and binding | ||||
* "jwk" header again used instead of "cnf" claim in DPoP proof | ||||
* renamed "Bearer-DPoP" token type to "DPoP" | ||||
* removed ability for key rotation | ||||
* added security considerations on request integrity | ||||
* explicit advice on extending DPoP proofs to sign other parts of | ||||
the HTTP messages | ||||
* only use the jkt#S256 in ATs | ||||
* iat instead of exp in DPoP proof JWTs | ||||
* updated guidance on token_type evaluation | ||||
-01 | ||||
* fixed inconsistencies | ||||
* moved binding and proof messages to headers instead of parameters | ||||
* extracted and unified definition of DPoP JWTs | ||||
* improved description | ||||
-00 | ||||
* first draft | ||||
Authors' Addresses | Authors' Addresses | |||
Daniel Fett | Daniel Fett | |||
Authlete | Authlete | |||
Email: mail@danielfett.de | Email: mail@danielfett.de | |||
Brian Campbell | Brian Campbell | |||
Ping Identity | Ping Identity | |||
Email: bcampbell@pingidentity.com | Email: bcampbell@pingidentity.com | |||
John Bradley | John Bradley | |||
Yubico | Yubico | |||
Email: ve7jtb@ve7jtb.com | Email: ve7jtb@ve7jtb.com | |||
Torsten Lodderstedt | Torsten Lodderstedt | |||
yes.com | Tuconic | |||
Email: torsten@lodderstedt.net | Email: torsten@lodderstedt.net | |||
Michael Jones | Michael Jones | |||
independent | Self-Issued Consulting | |||
Email: michael_b_jones@hotmail.com | Email: michael_b_jones@hotmail.com | |||
URI: https://self-issued.info/ | URI: https://self-issued.info/ | |||
David Waite | David Waite | |||
Ping Identity | Ping Identity | |||
Email: david@alkaline-solutions.com | Email: david@alkaline-solutions.com | |||
End of changes. 205 change blocks. | ||||
875 lines changed or deleted | 725 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. |