-
Notifications
You must be signed in to change notification settings - Fork 223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add dpop nonce support #1569
Add dpop nonce support #1569
Conversation
…auth server supplied nonces
This looks great, I will try to implement and test it today |
src/OidcClient.ts
Outdated
}); | ||
} catch (err) { | ||
if (err instanceof ErrorDPoPNonce) { | ||
extraHeaders!["DPoP"] = await this.getDpopProof(this.settings.dpop!.store, err.nonce); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not doing this before hand? I dislike doing exchangeRefreshToken
twice...
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1569 +/- ##
==========================================
+ Coverage 80.53% 81.31% +0.78%
==========================================
Files 45 48 +3
Lines 1731 1884 +153
Branches 344 371 +27
==========================================
+ Hits 1394 1532 +138
- Misses 299 309 +10
- Partials 38 43 +5
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
I apologize if this is the wrong place to put this comment. Chris I pulled your latest code (14 files changed), rebuilt the npm and put the rebuilt package in my application. Everything builds fine, however I still get the same message "The DPoP proof JWT header is missing.". I do get a prompt and I do login, then I get that message. Do you have an example project that I can test this with? Thank you. |
Yes, I have been using the What IdP are you using? |
Thank you. I made a little more progress. I need to review your oidc-client-context project/example further. I am connecting to a US Government Open ID Connect internal auth server. I was able to progress past the DPoP Nonce error message. They turn the dev servers off around 7PM so I can't get the exact error message I was getting but I will post it in the morning. But it was something along the lines it could not retrieve the publicKey. |
Thanks for contributing. As I am not using the dpop feature I really appreciate if you can help supporting this feature within this library. Maybe you have time to help supporting other features as well... |
Here is the error I am receiving (I am connecting to my site using HTTPS://). I tried in Chrome and Edge and it throws the same error. It does work in Firefox though and auth.IsAuthenticated shows TRUE. I traced it back to line 190 from CryptoUtils.ts. "Could not retrieve dpop keys from storage: Cannot read properties of undefined (reading 'publicKey')" I am doing a auth.signinRedirect(), in UserManager.ts I see line 177 is where we do a generateDPoPJkt call Here is my oidcConfig: const oidcConfig = { |
Ok, can you check what is stored in indexedDb in your browser under Here is an example of what you might see: My first thought is that it's possible that you have an out of date object stored that may need to be cleared. The missing public key indicates that the object being retrieved is not in the shape we expect. This change introduced a breaking change in that the object that we store for DPoP changed to include storing the nonce. If the object in indexedDb looks different, delete it and try logging in again. If this is not the case, would you mind starting an issue and we can work from there? This will allow any findings to be more discoverable for others in the future. The other possibility may be that for some reason nothing is being written to indexedDb. If that is the case, can you tell me what browser you are using incl the version, any plugins, etc, and perhaps set up some tracing in the debugger to look at what happens when the Or it could be something else of course 😅 If so, create an issue as mentioned and we will figure it out. |
Very happy to help. My next PR will document the DPoP feature and I am happy so support it. |
Thank you! I checked the IndexDB storage option in Chrome and it only shows IndexDB and no database. But oddly enough I tried the website/app and it works now. I tried in Edge and it did show the IndexDb>oidc>dpop and a key. I deleted the oidc database, retried it in Edge and it works correctly. Not sure what was going on with Chrome regarding the IndexDb database not showing anything but all browsers work now. Thank you very much for your hard work. If you need me to test anything let me know. |
Interesting, but good news. Very odd. In your environment, do resource servers (e.g. APIs that you call) also require the dpop nonce? I'd be interested in any experiences regarding that because it is a client concern (e.g. handling receiving, storing and using the nonce value). If you look at the |
I saw your callApi method., thank you for that example. Yes I am working on the backend web api as well. I will use C# .NET Core Web API for the backend. I believe it will need to validate the nonce and dpop values with the auth server on all requests. That is my next task. When I get that working I can send you over an example or check it in at github. |
No problem. Take a look at the Duende example API DPoP code. This extends .NET's built in JwtBearer validation. Good luck 👍 |
Thank you! I will take a look. I appreciate all the help you have been. |
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [oidc-client-ts](https://github.com/authts/oidc-client-ts) | dependencies | minor | [`3.0.1` -> `3.1.0`](https://renovatebot.com/diffs/npm/oidc-client-ts/3.0.1/3.1.0) | --- ### Release Notes <details> <summary>authts/oidc-client-ts (oidc-client-ts)</summary> ### [`v3.1.0`](https://github.com/authts/oidc-client-ts/releases/tag/v3.1.0) [Compare Source](authts/oidc-client-ts@v3.0.1...v3.1.0) oidc-client-ts v3.1.0 is a minor release. No longer using `crypto-js` package, but built-in browser [crypto.subtle](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/subtle) module. Crypto.subtle is available only in [secure contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) (HTTPS). Also have a look into the [migration](https://github.com/authts/oidc-client-ts/blob/main/docs/migration.md) info. #### Changelog: - Fixes: - [#​1666](authts/oidc-client-ts#1666): fix link in docs to issue - [#​1600](authts/oidc-client-ts#1600): updated docs about logger - [#​1589](authts/oidc-client-ts#1589): fix compiler error for target=ES2022 - [#​1539](authts/oidc-client-ts#1539): fix small typo in `signinCallback` doc in UserManager.ts - [#​1504](authts/oidc-client-ts#1504): typo in sample app config - [#​1490](authts/oidc-client-ts#1490): fix the return type of `signinCallback` - [#​1443](authts/oidc-client-ts#1443): fixes typos in docs - Features: - [#​1672](authts/oidc-client-ts#1672): make `signoutCallback` return signout response if request_type is so:r - [#​1626](authts/oidc-client-ts#1626): add `popupSignal` property to `signinPopup` and `signoutPop` - [#​1580](authts/oidc-client-ts#1580): add dpop docs - [#​1569](authts/oidc-client-ts#1569): add dpop nonce support - [#​1457](authts/oidc-client-ts#1457): add extra headers - [#​1461](authts/oidc-client-ts#1461): add demonstrating proof of possession - [#​1430](authts/oidc-client-ts#1430): add global `requestTimeoutInSeconds` setting - [#​1405](authts/oidc-client-ts#1405): allow using default scopes from authorization server thanks to [@​klues](https://github.com/klues), [@​smujmaiku](https://github.com/smujmaiku), [@​mftruso](https://github.com/mftruso), [@​peetck](https://github.com/peetck), [@​dbfr3qs](https://github.com/dbfr3qs), [@​mottykohn](https://github.com/mottykohn), [@​noshiro-pf](https://github.com/noshiro-pf), [@​dbfr3qs](https://github.com/dbfr3qs), [@​grjan7](https://github.com/grjan7) and [@​natergj](https://github.com/natergj) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4xMDkuMCIsInVwZGF0ZWRJblZlciI6IjM4LjEwOS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=--> Reviewed-on: https://git.tristess.app/alexandresoro/ouca/pulls/191 Reviewed-by: Alexandre Soro <code@soro.dev> Co-authored-by: renovate <renovate@git.tristess.app> Co-committed-by: renovate <renovate@git.tristess.app>
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [oidc-client-ts](https://github.com/authts/oidc-client-ts) | dependencies | minor | [`3.0.1` -> `3.1.0`](https://renovatebot.com/diffs/npm/oidc-client-ts/3.0.1/3.1.0) | --- ### Release Notes <details> <summary>authts/oidc-client-ts (oidc-client-ts)</summary> ### [`v3.1.0`](https://github.com/authts/oidc-client-ts/releases/tag/v3.1.0) [Compare Source](authts/oidc-client-ts@v3.0.1...v3.1.0) oidc-client-ts v3.1.0 is a minor release. No longer using `crypto-js` package, but built-in browser [crypto.subtle](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/subtle) module. Crypto.subtle is available only in [secure contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) (HTTPS). Also have a look into the [migration](https://github.com/authts/oidc-client-ts/blob/main/docs/migration.md) info. #### Changelog: - Fixes: - [#​1666](authts/oidc-client-ts#1666): fix link in docs to issue - [#​1600](authts/oidc-client-ts#1600): updated docs about logger - [#​1589](authts/oidc-client-ts#1589): fix compiler error for target=ES2022 - [#​1539](authts/oidc-client-ts#1539): fix small typo in `signinCallback` doc in UserManager.ts - [#​1504](authts/oidc-client-ts#1504): typo in sample app config - [#​1490](authts/oidc-client-ts#1490): fix the return type of `signinCallback` - [#​1443](authts/oidc-client-ts#1443): fixes typos in docs - Features: - [#​1672](authts/oidc-client-ts#1672): make `signoutCallback` return signout response if request_type is so:r - [#​1626](authts/oidc-client-ts#1626): add `popupSignal` property to `signinPopup` and `signoutPop` - [#​1580](authts/oidc-client-ts#1580): add dpop docs - [#​1569](authts/oidc-client-ts#1569): add dpop nonce support - [#​1457](authts/oidc-client-ts#1457): add extra headers - [#​1461](authts/oidc-client-ts#1461): add demonstrating proof of possession - [#​1430](authts/oidc-client-ts#1430): add global `requestTimeoutInSeconds` setting - [#​1405](authts/oidc-client-ts#1405): allow using default scopes from authorization server thanks to [@​klues](https://github.com/klues), [@​smujmaiku](https://github.com/smujmaiku), [@​mftruso](https://github.com/mftruso), [@​peetck](https://github.com/peetck), [@​dbfr3qs](https://github.com/dbfr3qs), [@​mottykohn](https://github.com/mottykohn), [@​noshiro-pf](https://github.com/noshiro-pf), [@​dbfr3qs](https://github.com/dbfr3qs), [@​grjan7](https://github.com/grjan7) and [@​natergj](https://github.com/natergj) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjM4LjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=--> Reviewed-on: https://git.tristess.app/alexandresoro/ouca/pulls/196 Reviewed-by: Alexandre Soro <code@soro.dev> Co-authored-by: renovate <renovate@git.tristess.app> Co-committed-by: renovate <renovate@git.tristess.app>
This is a first cut aimed at adding
DPoP
nonce support. I initially removed this feature in the original PR and this is a follow up.This is very experimental and open to change. @pamapa I would really appreciate your thoughts as to how this could be done more cleanly 🙏🏼
The main functionality is supporting Authorization Server Provided Nonces.
According to the spec, if/when an AS requires the use of a nonce and a token request is made without a nonce claim within the DPoP proof JWT, the AS responds with a specific 400 bad request that includes a response header
dpop-nonce
which contains the nonce value to be used. The client is then expected to regenerate its DPoP proof again with the included nonce, and then retry the token request.e.g.
In order to accomodate this I have added a new abstraction
DPoPState
, which is an object that contains both the CryptoKeyPair and the optional nonce value. I have altered theDPoPStore
interface to accomodate this as the nonce can be used repeatedly for token requests until the AS decides to invalidate.Which brings me to my next point, the spec is quite open as to how an AS may provide a new nonce.
I attempted to try and add a way to handle a new nonce upon a 200 response but it was going to be messy and potentially involved altering the
SigninResponse
class, which didn't feel right. I looked at how IdentityServer issues new nonces and they just re-use the 400 bad request method. I think we should leave this out for the time being.In regards to supporting Resource Server provided nonces, that is a lot simpler as the client should manage storing and renewing the resource provided nonce as it will be returned on a client initiated fetch request to the RS - it has nothing to do with
oidc-client-ts
. For now I have opted to provide a way to supply the nonce as an optional parameter when creating the DPoPProof on the user manager class. We can revisit if we want to offer a way for clients to store the RS provided nonce values and/or provide helpers to manage them, but this interaction falls outside the relationship between the client and the AS.Checklist