# Demonstrating Proof-of-Possession (DPoP)

> Learn how to leverage Demonstrating Proof-of-Possession when using OidcClient to build a native OIDC client.

[DPoP](https://datatracker.ietf.org/doc/html/rfc9449) specifies how to bind an asymmetric key stored within a JSON Web Key (JWK) to an access token. This will make the access token bound to the key such that if the access token were to leak, it cannot be used without also having access to the private key of the corresponding JWK.

The `Duende.IdentityModel.OidcClient.Extensions` library adds supports for DPoP to OidcClient.

## DPoP Key

[Section titled âDPoP Keyâ](#dpop-key)

Before we begin, your application needs to have a DPoP key in the form of a JSON Web Key (or JWK). According to the [DPoP specification](https://datatracker.ietf.org/doc/html/rfc9449), this key needs to use an asymmetric algorithm (âRSâ, âESâ, or âPSâ style).

Note

The client application is responsible for creating the DPoP key, rotating it, and managing its lifetime. For as long as there are access tokens (and possibly refresh tokens) bound to a DPoP key, that key needs to remain available to the client application.

You can create a JWK in .NET using the `Duende.IdentityModel.OidcClient.Extensions` library. The `JsonWebKeys` class has several static methods to help with creating JWKs using various algorithms.

Program.cs

```csharp
using Duende.IdentityModel.OidcClient.DPoP;


// Creates a JWK using the PS256 algorithm:
var jwk = JsonWebKeys.CreateRsaJson();


Console.WriteLine(jwk);
```

Caution

In a production scenario, youâll want to store this JWK in a secure location and use ASP.NETâs [data protection](https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/) to further protect the JWK. See [our data protection guide](/identityserver/deployment/#aspnet-core-data-protection) for more information.

## Initializing the OIDC client with DPoP support

[Section titled âInitializing the OIDC client with DPoP supportâ](#initializing-the-oidc-client-with-dpop-support)

We will need to extend the `OidcClientOptions` before we can use DPoP.

After creating the `OidcClientOptions` to connect our client application with the Identity Provider, we retrieve a JWK to use for DPoP, and add that JWK to our `options` by calling the `ConfigureDPoP` extension method:

Program.cs

```csharp
using Duende.IdentityModel.OidcClient;
using Duende.IdentityModel.OidcClient.DPoP;


var options = new OidcClientOptions
{
    Authority = "https://demo.duendesoftware.com",
    ClientId = "native.dpop",
    Scope = "openid profile email offline_access",
    // ...
};


// creates a new JWK, or returns an existing one
var jwk = GetDPoPJwk();


// Enable DPoP
options.ConfigureDPoP(jwk);


var oidcClient = new OidcClient(options);
```

## Proof Tokens for the API

[Section titled âProof Tokens for the APIâ](#proof-tokens-for-the-api)

Now that weâve configured the `OidcClientOptions` with DPoP support and created an `OidcClient` instance, you can use this instance to create an `HttpMessageHandler` which will:

* manage access and refresh tokens
* add DPoP proof tokens to HTTP requests

The `OidcClient` provides `CreateDPoPHandler` as a convenience method to create such a handler, which can be used with the .NET `HttpClient`.

Program.cs

```csharp
var sessionRefreshToken = "..."; // read from a previous session, if any


var handler = oidcClient.CreateDPoPHandler(jwk, sessionRefreshToken);
var apiClient = new HttpClient(handler);
```

For a full example, have a look at our [WPF with the system browser](https://github.com/DuendeSoftware/foss/tree/main/identity-model-oidc-client/samples/Wpf) sample.
-----