Course contentsShow
← C#
Lesson 1240 of 1,90811. Identity, Security, and ClaimsFree lesson

Implementing Proof-of-Possession

Use DPoP tokens to ensure that only the intended recipient can use a bearer token.

In this lesson, you will learn how to strengthen your API security by implementing Demonstrating Proof-of-Possession (DPoP) to ensure that bearer tokens cannot be stolen and reused by unauthorized parties.

The Problem with Standard Bearer Tokens

In a typical OAuth flow, an access token is a "bearer" token—meaning that anyone who possesses it can use it to access your resources. If a token is intercepted via a man-in-the-middle attack or leaked from logs, an attacker can replay that token to impersonate the legitimate client.

The DPoP Solution

DPoP (Demonstrating Proof-of-Possession) binds an access token to a specific cryptographic key pair generated by the client. Instead of just sending the token, the client sends a "DPoP Proof"—a unique, signed JWT that demonstrates the client holds the private key corresponding to the public key the token is bound to.

When your C# API receives a request, it validates two things:

  1. The standard access token.
  2. The DPoP proof, ensuring the cnf (confirmation) claim in the access token matches the public key used to sign the DPoP header.

A Simplified Workflow

When a client makes a request, they attach a DPoP header containing the proof:

// Example conceptual proof structure
var dpopProof = new DPoPHeader 
{
    HttpMethod = "GET",
    HttpUri = "https://api.example.com/data",
    Jti = Guid.NewGuid().ToString(),
    Iat = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
};

// The client signs this with their private key
string proof = SignProof(dpopProof, privateKey);
httpClient.DefaultRequestHeaders.Add("DPoP", proof);

On your server, you must intercept the request, extract the DPoP header, and verify that the jwk (JSON Web Key) provided in the header matches the proof's signature and the expected binding. If the proof doesn't match the token's cnf claim, the server rejects the request, even if the token itself is technically valid. This prevents an attacker from using a stolen token because they lack the client's private key required to generate a new, valid DPoP proof for their own malicious requests.

Key Takeaway: Implementing DPoP elevates your security from "bearer-based" to "possession-based," ensuring that only the specific client that requested the token can successfully use it.