Skip to content
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

[WIP] fix: correctly respect client expiry #2122

Draft
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

ThisIsMissEm
Copy link
Contributor

This PR fixes the bug where dynamically registered clients did not expire, despite the server indicating that they should expiry at a given time.

  • I've added a unit test to test for potential regressions of this bug.
  • The changelog has been updated, if applicable.
  • Commits in this PR are minimal and have descriptive commit messages.

@ThisIsMissEm ThisIsMissEm requested a review from a team as a code owner April 30, 2022 02:38
@vercel vercel bot temporarily deployed to Preview April 30, 2022 02:40 Inactive
expect(mockFetch).toHaveBeenCalled();
});

it("registers a new client if the one in storage has no expiry stored", async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NSeydoux I think this is what we'll want, because otherwise someone may have a valid client, but we hadn't stored the expiry, in which case registering a new client resolves that missing expiry.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Apr 30, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 3280347:

Sandbox Source
solid-client-auth-browser-demo Configuration

@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production April 30, 2022 02:42 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production April 30, 2022 02:42 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next April 30, 2022 02:42 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next April 30, 2022 02:42 Inactive
const infoToSave: Record<string, string> = {
clientId: registeredClient.metadata.client_id,
idTokenSignedResponseAlg:
registeredClient.metadata.id_token_signed_response_alg ?? signingAlg,
};
if (registeredClient.metadata.client_secret) {
infoToSave.clientSecret = registeredClient.metadata.client_secret;
infoToSave.clientExpiresAt = clientExpiresAt.toString();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may always want to store this, though technically client_secret_expires_at is only returned if a client_secret is returned: https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse

@vercel vercel bot temporarily deployed to Preview April 30, 2022 02:44 Inactive
@@ -143,18 +149,30 @@ export default class ClientRegistrar implements IClientRegistrar {
}
);

let clientExpiresAt = 0;
if (
typeof registeredClient.metadata.client_secret_expires_at === "number"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: openid-client doesn't actually verify that client_secret_expires_at is present and that it is in the future, I've added a set of checks in oidc-client-ext to verify these for the browser, but for server we don't currently have these checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory here we could receive back a client with a client_secret_expires_at in the past, if the users' clock time on their server is ahead of the IdP's clock time.

Can we assume that users and IdP's can configure their servers to have a synchronised clock time?

const mockFetch = (jest.fn() as any).mockResolvedValueOnce(
/* eslint-disable camelcase */
new NodeResponse(
JSON.stringify({
client_id: "some id",
client_secret: "some secret",
// Expire this client in 5 seconds:
client_secret_expires_at: currentTime / 1000 + 5,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want a test for the behaviour when client_secret_expires_at is in the past, as the registerClient would fail in this case, which would likely blow up the code for ClientRegistrar in browser.

@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production April 30, 2022 03:06 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production April 30, 2022 03:06 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next April 30, 2022 03:06 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next April 30, 2022 03:06 Inactive
@vercel vercel bot temporarily deployed to Preview April 30, 2022 03:10 Inactive
@ThisIsMissEm
Copy link
Contributor Author

E2E tests are currently failing because of how the silentlyAuthenticate function works, which results in the existing client being wiped out when we try to authenticate again.

@ThisIsMissEm ThisIsMissEm marked this pull request as draft May 4, 2022 12:40
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production May 4, 2022 18:11 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next May 4, 2022 18:11 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production May 4, 2022 18:11 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next May 4, 2022 18:11 Inactive
@vercel vercel bot temporarily deployed to Preview May 4, 2022 18:11 Inactive
sessionInfo.issuer === undefined
) {
return null;
}

// FIXME: verify client is still valid
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually taken care of by ClientRegistrar — if the client isn't valid, then a new one will be requested.

Valid Client: has clientId & clientExpiresAt == 0 or clientExpiresAt > now

@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production May 4, 2022 19:18 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next May 4, 2022 19:18 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production May 4, 2022 19:18 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production May 20, 2022 00:13 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next May 20, 2022 00:13 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production May 20, 2022 00:13 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next May 20, 2022 00:13 Inactive
@vercel vercel bot temporarily deployed to Preview May 20, 2022 00:14 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production May 20, 2022 14:37 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next May 20, 2022 14:37 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Production May 20, 2022 14:37 Inactive
@ThisIsMissEm ThisIsMissEm temporarily deployed to ESS Dev-Next May 20, 2022 14:37 Inactive
@vercel vercel bot temporarily deployed to Preview May 20, 2022 14:37 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant