Use DPoP when a server must make OAuth requests without allowing a copied access token to be replayed by whoever obtains it. The client signs a proof JWT with a private key, the authorization server binds the issued token to that key, and the resource server checks the proof before accepting the token. Token exchange then lets one service trade a subject token for a downstream token, optionally identifying an acting service. In Spring Security 7, token exchange is an extension grant that must be enabled explicitly; DPoP proof generation and validation must be applied at both the token endpoint and the protected resource.
Why combine DPoP with token exchange?
A normal OAuth bearer token is usable by any party that presents it. If a token leaks through a log, proxy, browser extension or compromised host, the thief can replay it until it expires or is revoked. DPoP (Demonstrating Proof of Possession) adds an application-layer sender constraint: the access token is associated with a public key, and every use must prove possession of the corresponding private key.
As an Amazon Associate I earn from qualifying purchases.
DPoP does not decide whether a caller is authorized. Scope, audience, issuer, subject and your application’s authorization rules still apply. DPoP answers a different question: whether the presenter holds the key to which the authorization server bound the token.
| Aspect | Bearer token | DPoP-bound token |
|---|---|---|
| Authorization header | Authorization: Bearer <token> |
Authorization: DPoP <token> |
| Proof of key possession | None | Signed JWT in a DPoP header on each request |
| Replay resistance | Anyone holding the token can replay it | Replay requires the private key and a valid, fresh proof |
| Token binding data | No confirmation key | JWT cnf.jkt thumbprint, or an equivalent value returned by introspection |
What a DPoP proof contains
The proof is a signed JWT carried in the DPoP HTTP header. Its JOSE header contains the public JWK and an appropriate asymmetric signing algorithm. The claims identify the request and prevent reuse.
#1 Best Overall
htmis the HTTP method, such asPOSTorGET.htuis the target URI, with the same host, scheme and path that the server validates.iatis the proof issue time; the server applies a clock-skew and freshness policy.jtiis a unique identifier that allows replay detection.athis required on protected-resource requests. It is the base64url-encoded SHA-256 hash of the access-token value.
A token request includes htm, htu, iat and jti. A resource request adds ath, because the proof must be tied to the exact access token being presented.
The two HTTP moments in a DPoP flow
1. Requesting a token
The server sends the OAuth request with a DPoP proof. The authorization server validates the signature, checks the request method and URI, applies freshness and replay rules, and verifies that the client is entitled to use the key. A successful response identifies the access token as DPoP-bound:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eyJ...",
"token_type": "DPoP",
"expires_in": 300
}
The token_type value is significant. A caller must not silently send a DPoP-bound token with the Bearer scheme.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
2. Calling the protected resource
The caller sends both the token and a newly signed proof. The proof must describe the resource request and include ath for that token:
GET /orders/123 HTTP/1.1
Host: api.example.test
Authorization: DPoP eyJ...
DPoP: eyJ...proof...
The resource server validates the proof signature and claims, computes the token thumbprint and token hash, and then applies ordinary OAuth authorization checks.
Token exchange as server-to-server delegation
Token exchange uses the OAuth extension grant type urn:ietf:params:oauth:grant-type:token-exchange. A service presents a subject token and asks the authorization server for a token suitable for a downstream audience or scope. The subject token represents the identity or delegation being carried forward. An optional actor token identifies the service performing the exchange, allowing policy to distinguish “the user” from “the service acting for the user.”
Spring Security models this request with TokenExchangeGrantRequest:
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →TokenExchangeGrantRequest request =
new TokenExchangeGrantRequest(
clientRegistration,
subjectToken,
actorToken);
The constructor accepts a ClientRegistration, an OAuth2Token subject token and an optional OAuth2Token actor token. Pass a null actor token only when the authorization policy intentionally treats the exchange as subject-only.
Rank #3
When the downstream token is DPoP-bound, the exchange request is still an access-token request and must carry a valid DPoP proof. The requirement applies regardless of the grant used, including client_credentials, refresh_token and token exchange.
Enabling token exchange in a Spring Security 7 client
Pin the Spring Security line first
The 7.0 documentation snapshot identifies version 7.0.7 and notes 7.1.1 as the latest stable version at the time it was captured. Pin the version used by your application, then verify the token-exchange APIs against the exact 7.x minor release you deploy; extension-grant configuration can evolve between minors.
Register the servlet response client
Token exchange is not enabled by default in the client. For a servlet application, create a RestClientTokenExchangeTokenResponseClient and register it with the token-exchange authorized-client provider used by your OAuth2AuthorizedClientManager.
@Bean
OAuth2AccessTokenResponseClient<TokenExchangeGrantRequest>
tokenExchangeTokenResponseClient() {
RestClientTokenExchangeTokenResponseClient client =
new RestClientTokenExchangeTokenResponseClient();
// Configure converters or handlers here when your authorization
// server requires non-default headers or parameters.
return client;
}
The servlet response client is designed for customization of request headers, request parameters, response conversion and error handling. Use those extension points to add a required audience, requested token type, resource indicator, client assertion or authorization-server-specific parameter without replacing the HTTP exchange implementation.
Rank #4
- Made in USA - Proudly produced in Ohio by a Veteran-owned business
- Comprehensive Coverage: This BookFactory log book includes essential fields such as post/shift, time of change, date, weather conditions, and a designated space for detailed notes. This ensures that all relevant information is captured and easily accessible.
- Sturdy Cover: The trans-lux cover protects the log book from wear and tear, ensuring its longevity and maintaining the integrity of your recorded data.
- Essential Security Tool: This log book is an indispensable tool for any organization that values security and accountability. It helps to prevent misunderstandings, improve communication, and ensure a smooth transition between shifts.
- Wire-O with Trans-lux cover, 100 Pages, Dimensions 8.5" x 11" - (Security-Pass-Down) Reorder SKU: LOG-100-7CW-PP(Security-Pass-Down)
Attach the provider to the authorized-client manager
Build an authorized-client provider that includes token exchange and point its access-token response client at the bean above. The exact builder overload should match the Spring Security 7 minor version on your classpath; the essential configuration is that the token-exchange provider is present and its response client is the RestClientTokenExchangeTokenResponseClient instance.
- Create the
TokenExchangeGrantRequestwith the registered client, subject token and optional actor token. - Pass that grant request through the token-exchange provider configured on the manager.
- Ensure the HTTP request converter adds a DPoP proof when the authorization server issues DPoP-bound tokens.
- Store the returned authorized client with the downstream audience and scopes that your service requested.
If the provider is omitted, the manager will not recognize the extension grant even though the authorization server supports it. A response-client bean by itself does not activate the grant.
Authorization-server configuration and token response
Spring Authorization Server’s token endpoint recognizes urn:ietf:params:oauth:grant-type:token-exchange and includes OAuth2TokenExchangeAuthenticationConverter by default. The authorization server still controls whether a particular client may exchange tokens, which token types are accepted, the permitted audiences and scopes, and whether the resulting access token is DPoP-bound.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchFor a DPoP-bound response, return token_type: DPoP and include the confirmation key thumbprint in the access token’s cnf.jkt claim when using a JWT access token. With an opaque token, expose the equivalent confirmation data through introspection so the resource server can perform the same comparison.
How a resource server validates the bound token
Validation is a sequence, not a single signature check:
- Read the
Authorization: DPoPheader and the separateDPoPproof header. Reject a DPoP-bound token sent with the Bearer scheme. - Parse and verify the proof JWT using the public JWK carried in its JOSE header. Enforce an allowed asymmetric algorithm set.
- Check
htmandhtuagainst the actual request, then enforce the acceptediatwindow and reject a reusedjti. - Compute the base64url SHA-256 hash of the presented access token and compare it with
ath. - Read the token’s
cnf.jktclaim, or obtain the confirmation key from introspection, and compare that thumbprint with the proof’s public JWK. - Only after sender constraint succeeds, validate issuer, audience, expiry, scope and application authorization.
The key lookup is therefore explicit: a JWT resource server reads cnf.jkt from the token, while an opaque-token resource server obtains the binding from introspection. A deployment that validates only the access-token signature but skips ath or cnf.jkt has not enforced DPoP.
Key lifecycle, replay and nonce decisions
Protect and rotate the private key
Keep the DPoP private key in a protected keystore or hardware-backed facility where practical. Rotation changes the public-key thumbprint, so coordinate key rollover with token lifetime and authorization-server acceptance of the new key. Do not copy private keys into logs, container images or build artifacts.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Make replay detection stateful enough
Store recently seen proof jti values for at least the validity window you accept for iat. Use a store shared by all instances that can receive the same request; a per-process cache leaves a replay gap behind a load balancer.
Handle nonce challenges
RFC 9449 allows a resource or authorization server to require a nonce. On a nonce challenge, obtain the server-provided value and include it in the next proof according to the server’s policy. Treat nonce storage as short-lived and scoped to the relevant issuer or resource; do not reuse a nonce indefinitely.
Quick Recap
Testing checklist
- Accept a correctly signed token-request proof and reject a proof whose
htmorhtudoes not match. - Reject stale
iatvalues, malformedjtivalues and a second use of the same proof identifier. - On a resource request, reject a missing or incorrect
ath. - Reject a proof whose public-key thumbprint differs from
cnf.jkt. - Reject a DPoP-bound token presented with
Authorization: Bearer. - Verify that token exchange fails when the client is not allowed to use the extension grant, when the subject token is invalid, and when requested audience or scope violates policy.
- Verify both subject-only exchange and subject-plus-actor exchange, including the authorization decisions associated with each.
- Run the same tests through every servlet instance and through the real proxy path so URI canonicalization and shared replay state are exercised.
Common integration failures
| Symptom | Likely cause | Correction |
|---|---|---|
| Unsupported grant type | The token-exchange provider was never registered on the authorized-client manager. | Add the token-exchange provider and connect the response client. |
| Invalid DPoP proof at the token endpoint | The proof’s method or URI describes a different endpoint, or the clock is outside the accepted window. | Generate the proof from the final request URL and synchronize clocks. |
| Resource rejects a valid-looking token | ath is missing or was calculated from a different token string. |
Hash the exact compact access-token value sent in the Authorization header. |
| Key binding mismatch | The proof key does not match the token’s cnf.jkt, often after an unsynchronized key rotation. |
Use the private key corresponding to the bound public JWK and manage rollover deliberately. |
| Exchange succeeds but downstream call fails | The exchanged token’s audience, scope or token type does not match the resource policy. | Request the downstream audience and scopes explicitly and send a DPoP proof when the returned token is DPoP-bound. |
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




