Skip to content

Commit 42ac071

Browse files
committed
Add DPoP page to inform about Duende.IdentityModel.OidcClient.Extensions
1 parent bce702e commit 42ac071

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
label: 'Advanced'
2+
order: 6
3+
collapsed: true
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
---
2+
title: Demonstrating Proof-of-Possession (DPoP)
3+
description: Learn how to leverage Demonstrating Proof-of-Possession when using OidcClient to build a native OIDC client.
4+
sidebar:
5+
label: DPoP
6+
order: 1
7+
---
8+
9+
{/* Should we repeat ourselves here? This is the same paragraph as for Duende.AccessTokenManagement */}
10+
11+
[DPoP][dpop-spec] specifies how to bind an asymmetric key stored
12+
within a JSON Web Key (JWK) to an access token. This will make the access token bound to the key such that if the
13+
access token were to leak, it cannot be used without also having access to the private key of the corresponding JWK.
14+
15+
The `Duende.IdentityModel.OidcClient.Extensions` library adds supports for DPoP to OidcClient.
16+
17+
## DPoP Key
18+
19+
Before we begin, your application needs to have a DPoP key, in the form of a
20+
JSON Web Key (or JWK). According to the [DPoP specification][dpop-spec], this
21+
key needs to use an asymmetric algorithm ("RS", "ES", or "PS" style).
22+
23+
:::note
24+
This means that the client application is responsible for creating the DPoP key,
25+
rotating it, and managing its lifetime. For as long as there are access tokens
26+
(and possibly refresh tokens) bound to a DPoP key, that key needs to remain
27+
available to the client application.
28+
:::
29+
30+
Creating a JWK in .NET is pretty straightforward using the `Duende.IdentityModel.OidcClient.Extensions` library:
31+
32+
```csharp
33+
// Program.cs
34+
using Duende.IdentityModel.OidcClient.DPoP;
35+
36+
// Creates a JWK using the PS256 algorithm:
37+
var jwk = JsonWebKeys.CreateRsaJson();
38+
39+
Console.WriteLine(jwk);
40+
```
41+
42+
:::caution
43+
In a production scenario, you'll want to store this JWK in a secure location
44+
and use DataProtection to further protect the JWK.
45+
:::
46+
47+
## Initializing the OIDC client with DPoP support
48+
49+
Now that we have a JWK, we need to extend the `OidcClientOptions` to configure DPoP:
50+
51+
```csharp
52+
// Program.cs
53+
using Duende.IdentityModel.OidcClient;
54+
using Duende.IdentityModel.OidcClient.DPoP;
55+
56+
var options = new OidcClientOptions
57+
{
58+
Authority = "https://demo.duendesoftware.com",
59+
ClientId = "native.dpop",
60+
Scope = "openid profile email offline_access",
61+
// ...
62+
};
63+
64+
// creates a new JWK, or returns an existing one
65+
var jwk = GetDPoPJwk();
66+
67+
// Enable DPoP
68+
options.ConfigureDPoP(jwk);
69+
70+
var oidcClient = new OidcClient(options);
71+
```
72+
73+
## Proof Tokens for the API
74+
75+
After configuring the `OidcClientOptions` with DPoP support and creating an
76+
`OidcClient` instance, you can use this instance to create an `HttpMessageHandler` which
77+
will:
78+
79+
- manage access and refresh tokens
80+
- add DPoP proof tokens to HTTP requests
81+
82+
```csharp
83+
// Program.cs
84+
var sessionRefreshToken = "..."; // read from a previous session, if any
85+
86+
var handler = oidcClient.CreateDPoPHandler(jwk, sessionRefreshToken);
87+
var apiClient = new HttpClient(handler);
88+
```
89+
90+
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.
91+
92+
[dpop-spec]: https://datatracker.ietf.org/doc/html/rfc9449

0 commit comments

Comments
 (0)