8. Authorization Server-Provided Nonce
This section specifies a mechanism using opaque nonces provided by the server that can be used to limit the lifetime of DPoP proofs. Without employing such a mechanism, a malicious party controlling the client (potentially including the end-user) can create DPoP proofs for use arbitrarily far in the future.
Including a nonce value contributed by the authorization server in the DPoP proof MAY be used by authorization servers to limit the lifetime of DPoP proofs. The server determines when to issue a new DPoP nonce challenge and if it is needed, thereby requiring the use of the nonce value in subsequent DPoP proofs. The logic through 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 the client in DPoP proofs sent. In this case, the authorization server responds to requests that do not include a nonce with an HTTP 400 (Bad Request) error response per Section 5.2 of [RFC6749] using use_dpop_nonce as the error code value. The authorization server includes a DPoP-Nonce HTTP header in the response supplying a nonce value to be used when sending the subsequent request. Nonce values MUST be unpredictable. This same error code is used when supplying a new nonce value when there was a nonce mismatch. The client will typically retry the request with the new nonce value supplied upon receiving a use_dpop_nonce error with an accompanying nonce value.
For example, in response to a token request without a nonce when the authorization server requires one, the authorization server can respond with a DPoP-Nonce value such as the following to provide a nonce value to include in the DPoP proof:
HTTP/1.1 400 Bad Request
DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v
{
"error": "use_dpop_nonce",
"error_description":
"Authorization server requires nonce in DPoP proof"
}
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 response, but there MUST NOT be more than one DPoP-Nonce header.
Upon receiving the nonce, the client is expected to retry its token request using a DPoP proof including the supplied nonce value in the nonce claim of the DPoP proof. An example unencoded JWT payload of such a DPoP proof including a nonce is shown below.
{
"jti": "-BwC3ESc6acc2lTc",
"htm": "POST",
"htu": "https://server.example.com/token",
"iat": 1562262616,
"nonce": "eyJ7S_zG.eyJH0-Z.HX4w-7v"
}
Figure 21: DPoP Proof Payload including a Nonce Value
The nonce is opaque to the client.
If the nonce claim in the DPoP proof does not exactly match a nonce recently supplied by the authorization server to the client, the authorization server MUST reject the request. The rejection response MAY include a DPoP-Nonce HTTP header providing a new nonce value to use for subsequent requests.
The intent is that clients need to keep only one nonce value and servers need to keep a window of recent nonces. That said, transient circumstances may arise in which the stored nonce values for the server and the client differ. However, this situation is self-correcting. With any rejection message, the server can send the client the nonce value it wants to use to the client, and the client can store that nonce value and retry the request with it. Even if the client and/or server discard their stored nonce values, that situation is also self-correcting because new nonce values can be communicated when responding to or retrying failed requests.
Note that browser-based client applications using CORS [WHATWG.Fetch] only have access to CORS-safelisted response HTTP headers by default. 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 application by including DPoP-Nonce in the Access-Control-Expose-Headers response header list value.
8.1. Nonce Syntax
The nonce syntax in ABNF as used by [RFC6749] (which is the same as the scope-token syntax) is shown below.
nonce = 1*NQCHAR
Figure 22: Nonce ABNF
8.2. Providing 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 supplied nonce in DPoP proofs until the server supplies a new nonce value.
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 in the response. The DPoP-Nonce HTTP header field uses the nonce syntax defined in Section 8.1. Each time this happens, it requires an extra protocol round trip.
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) response from the previous request. The client MUST use the new nonce value supplied for the next token request and for all subsequent token requests until the authorization server supplies a new nonce.
Responses that include the DPoP-Nonce HTTP header should be uncacheable (e.g., using Cache-Control: no-store in response to a GET request) to prevent the response from being used to serve a subsequent request and a stale nonce value from being used as a result.
An example 200 OK response providing a new nonce value is shown below.
HTTP/1.1 200 OK
Cache-Control: no-store
DPoP-Nonce: eyJ7S_zG.eyJbYu3.xQmBj-1
Figure 23: HTTP 200 Response Providing the Next Nonce Value