-
-
Notifications
You must be signed in to change notification settings - Fork 54
/
dpop.diff
92 lines (83 loc) · 2.55 KB
/
dpop.diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
diff --git a/examples/oauth.ts b/examples/dpop.ts
index d55e62d..4cb7a95 100644
--- a/examples/oauth.ts
+++ b/examples/dpop.ts
@@ -15,6 +15,12 @@ let client_secret!: string
* Server.
*/
let redirect_uri!: string
+/**
+ * In order to take full advantage of DPoP you shall generate a random private key for every
+ * session. In the browser environment you shall use IndexedDB to persist the generated
+ * CryptoKeyPair.
+ */
+let DPoPKeys!: oauth.CryptoKeyPair
// End of prerequisites
@@ -24,6 +30,7 @@ const as = await oauth
const client: oauth.Client = { client_id }
const clientAuth = oauth.ClientSecretPost(client_secret)
+const DPoP = oauth.DPoP(client, DPoPKeys)
const code_challenge_method = 'S256'
/**
@@ -64,16 +71,29 @@ let access_token: string
const currentUrl: URL = getCurrentUrl()
const params = oauth.validateAuthResponse(as, client, currentUrl, state)
- const response = await oauth.authorizationCodeGrantRequest(
- as,
- client,
- clientAuth,
- params,
- redirect_uri,
- code_verifier,
- )
+ const authorizationCodeGrantRequest = () =>
+ oauth.authorizationCodeGrantRequest(
+ as,
+ client,
+ clientAuth,
+ params,
+ redirect_uri,
+ code_verifier,
+ { DPoP },
+ )
+
+ let response = await authorizationCodeGrantRequest()
+
+ const processAuthorizationCodeResponse = () =>
+ oauth.processAuthorizationCodeResponse(as, client, response)
- const result = await oauth.processAuthorizationCodeResponse(as, client, response)
+ let result = await processAuthorizationCodeResponse().catch(async (err) => {
+ if (oauth.isDPoPNonceError(err)) {
+ response = await authorizationCodeGrantRequest()
+ return processAuthorizationCodeResponse()
+ }
+ throw err
+ })
console.log('Access Token Response', result)
;({ access_token } = result)
@@ -81,11 +101,22 @@ let access_token: string
// Protected Resource Request
{
- const response = await oauth.protectedResourceRequest(
- access_token,
- 'GET',
- new URL('https://rs.example.com/api'),
- )
+ const protectedResourceRequest = () =>
+ oauth.protectedResourceRequest(
+ access_token,
+ 'GET',
+ new URL('https://rs.example.com/api'),
+ undefined,
+ undefined,
+ { DPoP },
+ )
+ let response = await protectedResourceRequest().catch((err) => {
+ if (oauth.isDPoPNonceError(err)) {
+ // the RS-signalled nonce is now cached, retrying
+ return protectedResourceRequest()
+ }
+ throw err
+ })
console.log('Protected Resource Response', await response.json())
}