Zum Inhalt springen
ecdsa.com

DPoP-Proof-Inspektor

Füge den Wert des DPoP-Headers einer Anfrage ein. Gib Methode und URL der Anfrage an – und das Access Token, falls eines mitgesendet wurde –, um alle Prüfungen eines Autorisierungs- oder Ressourcenservers auszuführen.

100 % lokal – alles läuft in deinem Browser, nichts wird an einen Server gesendet

Quelle: RFC 9449 §4.1, Abbildung 2, und §7.1, Abbildung 13; der jkt ist der Wert aus RFC 9449 §6.1. Geprüft zum Zeitpunkt aus dem Claim iat des Proofs.

Der Wert des DPoP-Headers der Anfrage
Die zugehörige Anfrage
Token-Bindung
Wird nur zur Berechnung von ath verwendet und nie in Links zum Teilen übernommen
Wird aus einem Access Token im JWT-Format gelesen, wenn das Feld leer bleibt
Richtlinie des Servers
dpop_signing_alg_values_supported
PrüfzeitpunktZeiten sind in UTC angegeben.

What the inspector checks

A DPoP proof (RFC 9449) is a short JWT that an OAuth client signs with its own private key and sends in the DPoP header of a request. It says "the holder of this key is making this request now": the header carries the public key as a jwk, the payload names the HTTP method (htm), the target URI (htu), a creation time (iat), a unique identifier (jti) and, when an access token is presented, the hash of that token (ath). A server that issued a DPoP-bound token accepts the token only together with a valid proof made with the bound key, so a token copied out of a log or a browser is useless on its own.

Section 4.3 of the RFC lists what a server must verify, and the inspector runs those steps in that order, reporting each one:

  1. There is exactly one DPoP header value, and it is a well-formed JWT.
  2. All required claims are present: jti, htm, htu, iat.
  3. typ is dpop+jwt — the explicit type that keeps a proof from ever being accepted as an ID token or an access token.
  4. alg names an asymmetric signature algorithm: never none, never an HS* MAC, and, if you list them, one of the algorithms your server advertises in dpop_signing_alg_values_supported.
  5. The jwk header holds a public key only. A proof whose key carries d, p, q or other private members means the client published its private key; the inspector flags it, and the share link refuses such a proof.
  6. The signature verifies with that embedded key, using the jose library restricted to the header's own algorithm.
  7. htm equals the request method — case-sensitively, as HTTP methods are.
  8. htu equals the request URI after normalisation.
  9. nonce equals the server's most recent DPoP-Nonce, when the server issued one.
  10. iat lies within the acceptance window: not in the future beyond the clock skew, and not older than the age you allow (five minutes by default).
  11. ath equals the hash of the presented access token.
  12. The proof's key is the key the token is bound to.

Replay detection by jti is server state, so the inspector reports the length of jti (RFC 9449 asks for at least 96 bits of randomness) but cannot know which values a server has already seen.

How htu is compared

The RFC compares htu with the request URI without query and fragment, after the syntax- and scheme-based normalisation of RFC 3986 §6.2.2 and §6.2.3: scheme and host in lower case, the default port removed, percent-encoded unreserved characters decoded, an empty path written as /. The inspector shows both normalised values next to each other, which is usually enough to spot the real culprit — a proxy that rewrote the host, an http:// URL behind a TLS terminator, or a client that put the query string into htu.

The jkt thumbprint and ath

Two values tie the pieces together. The first is the JWK thumbprint of the proof key (RFC 7638): the SHA-256 hash of the key's required members in lexicographic order, base64url-encoded. An authorization server writes it into a JWT access token as cnf.jkt, returns it from introspection, or receives it in advance as the dpop_jkt authorization request parameter. The inspector computes it, lets you copy it, and compares it with the value you give — or with the cnf.jkt it reads from a JWT access token, without verifying that token's own signature.

The second is ath: base64url(SHA-256(ASCII(access token))). It binds the proof to one token, so a proof captured with one token cannot be replayed with another. To check it, paste the access token; it is hashed in the page and is never placed into share links, because a token presented to a server that does not enforce the binding still works as a bearer token.

Going further

DPoP binds a token to a key but signs only the method and the URL. When the body and headers of a request must be protected too, that is the job of HTTP Message Signatures. To look inside an access token itself, paste it into the JWT debugger; to validate an OpenID Connect ID token issued in the same flow, use the OIDC token validator. The whole flow, with client and server code, is in DPoP explained.