iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Use DPoP when a server must ensure that a stolen OAuth token cannot be replayed by an attacker. In Spring Security 7, the pattern is: create a signed DPoP proof for the token request, obtain a token_type of DPoP, then send the downstream request with both Authorization: DPoP and a fresh proof. Token exchange adds the delegation step, allowing your server to trade an incoming subject token—and optionally an actor token—for a downstream access token.
What DPoP protects
A bearer access token is usable by whoever possesses it. If it is copied from a log, proxy, browser, memory dump or compromised host, the copier can present it until it expires or is revoked.
Demonstrating Proof of Possession (DPoP) is an application-layer sender constraint. The authorization server binds the token to a public key. The caller must then prove possession of the corresponding private key on every protected operation. DPoP does not replace scopes, roles, audience checks or business authorization; it adds proof that the presenter is the key holder.
| Bearer flow | DPoP flow |
|---|---|
Authorization: Bearer access-token |
Authorization: DPoP access-token plus a signed DPoP proof |
| Possession of the token is sufficient | The request must also be signed by the private key bound to the token |
| Replay resistance depends mainly on expiry, revocation and transport security | Replay of the token alone fails without the bound private key; proof replay is controlled with jti, time checks and, where required, a server nonce |
The two DPoP moments
1. The token request
The client places a compact signed JWT in the DPoP HTTP header. Its protected header identifies the DPoP type and carries the public JWK; its payload includes:
#1 Best Overall
htm: the HTTP method, such asPOSThtu: the token-endpoint URL, with the form required by the DPoP specificationiat: the issuance timejti: a unique proof identifier
The proof is signed with the private key corresponding to the embedded public key. This proof is required for DPoP-bound access-token requests regardless of the OAuth grant, including client_credentials and refresh_token. That requirement is important when the grant is token exchange: exchanging a token does not bypass DPoP proof validation.
POST /oauth2/token
DPoP: eyJ...signed-proof...
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=eyJ...subject-token...
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
A successful DPoP-bound response identifies itself with token_type: DPoP. Treat that value as a protocol signal: the resource request must use the DPoP authorization scheme, not the Bearer scheme.
2. The protected-resource request
For each resource call, create a new proof with the method and URL of that request. The payload also includes ath, the hash of the access-token value. Send both headers:
GET /orders/4815
Authorization: DPoP eyJ...access-token...
DPoP: eyJ...fresh-proof...
The resource server validates the proof signature and claims, hashes the presented token and compares that value with ath, then compares the proof’s public-key thumbprint with the token’s cnf.jkt confirmation claim. With an opaque token, the same binding information must come from introspection. A mismatch in the key thumbprint or token hash is an authentication failure even when the token is otherwise valid.
What OAuth token exchange adds
Token exchange is an OAuth extension grant for server-to-server delegation. Your application receives a token representing a subject, then asks an authorization server for a token suitable for a downstream resource. The original token is the subject token. An optional actor token represents the service performing the exchange.
| Delegation shape | Meaning | Use when |
|---|---|---|
| Subject only | The downstream token represents the original caller; the exchanging service is not separately asserted in the request. | The authorization server’s policy can derive the delegation from the subject token and client authentication. |
| Subject plus actor | The downstream decision can distinguish the end user (subject) from the service acting for that user (actor). | Auditing, least privilege or policy requires explicit on-behalf-of semantics. |
In Spring Security, TokenExchangeGrantRequest models this input with ClientRegistration, a required OAuth2Token subject token and an optional OAuth2Token actor token:
Rank #3
TokenExchangeGrantRequest request =
new TokenExchangeGrantRequest(clientRegistration, subjectToken, actorToken);
The authorization server’s token endpoint recognizes urn:ietf:params:oauth:grant-type:token-exchange. Spring Authorization Server includes OAuth2TokenExchangeAuthenticationConverter in the endpoint’s authentication-converter chain by default, and it lists DPoP-bound access tokens as a supported token type when DPoP is configured.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteEnable token exchange in a Spring Security 7 client
Pin the client dependency
The Spring Security documentation set used for this guide identifies 7.0.7; it also reported 7.1.1 as the latest stable version at crawl time. Pin the minor version used by your application and recheck the API before moving to a later 7.x release.
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>7.0.7</version>
</dependency>
Use the matching Spring Security version for the rest of the security modules in the application rather than mixing minors.
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)
Register the response client
Token exchange is not enabled by default in the OAuth2 client. The servlet implementation is RestClientTokenExchangeTokenResponseClient. Create it as the response client for the token-exchange provider (or configure the equivalent response-client bean used by your OAuth2AuthorizedClientManager):
@Bean
OAuth2AccessTokenResponseClient<TokenExchangeGrantRequest>
tokenExchangeTokenResponseClient() {
RestClientTokenExchangeTokenResponseClient client =
new RestClientTokenExchangeTokenResponseClient();
return client;
}
When constructing the authorized-client manager, explicitly register Spring Security 7’s token-exchange provider and supply this response client. If you omit that provider registration, ordinary client-registration and authorization-code support can work while a token-exchange request is never selected.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
RestClientTokenExchangeTokenResponseClient is designed for customization of outgoing headers, request parameters, response conversion and error handling. Use those hooks to add the subject and actor parameters required by your authorization server, ensure the DPoP header is generated for the exact token-endpoint URL, and map protocol errors into useful operational logs without recording token values.
Build the exchange request
- Resolve the
ClientRegistrationfor the downstream authorization server. - Convert the inbound credential into an
OAuth2Tokensubject token, preserving its value and token type. - Create an actor token only when the authorization policy requires explicit service-on-behalf-of semantics.
- Construct
TokenExchangeGrantRequestand pass it to the registered token-exchange response client or authorized-client manager. - Require a
DPoPtoken response before sending the downstream call; do not silently downgrade it to Bearer handling.
Configure the authorization server side
The authorization server must accept the token-exchange grant, authenticate the calling client, validate the subject token, apply policy to any actor token, and issue a token for the intended audience. If DPoP is requested, it must validate the DPoP proof on the token request and bind the resulting access token to the proof key.
- Accept the grant type
urn:ietf:params:oauth:grant-type:token-exchange. - Validate the subject token’s issuer, audience, expiry, scopes and any exchange-specific policy.
- Validate an actor token separately; do not treat it as interchangeable with the subject token.
- Issue
token_type: DPoPand include the key binding represented bycnf.jktwhen the result is DPoP-bound. - Return an OAuth error response for an invalid grant, invalid subject token, unauthorized actor or unacceptable audience.
Because DPoP proof is required for token requests regardless of grant type, the same rule applies when the authorization server receives an exchange request, a refresh request or a client-credentials request.
Validate DPoP at the resource server
- Require the
Authorization: DPoPscheme for a DPoP-bound token. - Require a
DPoPheader and parse its signed JWT. - Validate the proof signature using the public JWK, permitted algorithms and key-use rules.
- Check
htmagainst the actual method andhtuagainst the protected-resource URL. - Check
iatagainst an allowed clock-skew window and reject a reusedjti; retain identifiers long enough to cover that window. - Hash the exact access-token string and compare the result with
ath. - Read the token’s
cnf.jktfrom the JWT or from introspection and compare it with the thumbprint of the proof key. - Only after these checks, continue with issuer, audience, scope and application authorization.
Some deployments use a nonce challenge. If the authorization server or resource server requires a nonce, return the protocol-defined nonce challenge, require the client to include that nonce in its next proof, and never accept an old proof merely because its signature is valid.
Key management and operational failure modes
- Private-key loss: a new key cannot satisfy an existing token’s
cnf.jkt. Rotate by obtaining a new token, not by editing the old token. - Shared keys across instances: horizontal workers need coordinated key storage or a deliberate per-instance issuance strategy; otherwise one worker may issue a token another cannot use.
- URL mismatches: reverse proxies can change scheme, host or path. Generate and validate
htufrom the externally visible URL agreed by all participants. - Clock drift: synchronize hosts and set a narrowly justified skew. Excessive tolerance weakens replay protection.
- Wrong authorization scheme: sending a DPoP-bound token as
Bearershould fail; fix the client rather than relaxing the resource server. - Missing provider registration: a token-exchange request may never be attempted when the provider is not explicitly enabled.
- Leaking credentials in logs: redact access tokens, subject tokens, actor tokens and complete DPoP proofs. Log request IDs and error codes instead.
Tests that catch integration bugs
- Valid token-request proof with correct
htm,htu,iatand uniquejti. - Rejected proof with an altered method, URL, signature, expired timestamp or reused
jti. - Resource request whose
athhashes a different token than the one in the authorization header. - Resource request signed by a different key than the token’s
cnf.jkt. - Successful subject-only exchange and policy-controlled subject-plus-actor exchange.
- Failed exchange for an invalid, expired or unauthorized subject or actor token.
- DPoP proof enforcement on
client_credentialsandrefresh_tokenrequests, not just token exchange. - Correct rejection when a DPoP-bound token is sent with the Bearer scheme.
Servlet and reactive applications
The concrete response-client class described here is the servlet RestClientTokenExchangeTokenResponseClient. A WebFlux application should use the reactive OAuth2 client integration available in the exact Spring Security minor it has pinned; do not assume that a servlet RestClient response client can be injected into a reactive manager. In either stack, preserve the same protocol obligations: proof on the token request, DPoP authorization on the resource request, ath matching and cnf.jkt matching.
Quick Recap
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.

