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

Refresh cached credentials after PreAuthenticate fails #101053

Merged
merged 9 commits into from
Apr 30, 2024

Conversation

rzikm
Copy link
Member

@rzikm rzikm commented Apr 15, 2024

Fixes #93340.

This PR adds logic which, after Pre-Authenticated request fails with 401, checks whether the user supplied creentials are different from the cached ones, and if so, replaces the old (stale) creds with the new ones.

An implementational obstacle was removing the old creds from the preauth cache, because of insufficient API surface of CredentialCache. Therefore:

  • The type was replaced with a simpler internal-only cache type
  • and credential matching (CredentialKey class mostly) was moved to common source and reused.

NetEventSource.Info(pool.PreAuthCredentials, $"Pre-authentication credentials changed, removing Basic credential uri={preAuthCredentialUri}, username={preAuthCredential.UserName}");
}
pool.PreAuthCredentials.Remove(preAuthCredentialUri!, BasicScheme);
}
Copy link
Member

Choose a reason for hiding this comment

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

While we lock the PreAuthCredentials the logic leading to this can run in parallel, right? Do we have concurrency problem when Remove can throw? Perhaps use TryRemove?

Copy link
Member Author

Choose a reason for hiding this comment

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

The method calls Dictionary<TKey, TValue>.Remove() internally, which does not throw if the key does not exist in the first place.

Copy link
Member Author

Choose a reason for hiding this comment

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

But considering parallel requests, since we drop the lock between removing the creds and adding new ones, there may be some weird behavior if a parallel request starts when in-between. So I will move the removal to the same lock scope.

Copy link
Member

@wfurt wfurt left a comment

Choose a reason for hiding this comment

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

LGTM

@rzikm
Copy link
Member Author

rzikm commented Apr 30, 2024

Test failures are known (HTTP3 tests which were addressed since the pipeline has run).

@rzikm rzikm merged commit 3fac575 into dotnet:main Apr 30, 2024
76 of 84 checks passed
michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
* Support refreshing credentials in pre-auth cache

* Fix minor bug in CredentialCache

* Add unit test

* Fix tests

* Fix tests attempt 2

* Merge two lock statements.

* Fix build
@karelz karelz added this to the 9.0.0 milestone May 14, 2024
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
* Support refreshing credentials in pre-auth cache

* Fix minor bug in CredentialCache

* Add unit test

* Fix tests

* Fix tests attempt 2

* Merge two lock statements.

* Fix build
@github-actions github-actions bot locked and limited conversation to collaborators Jun 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HttpClientHandler with PreAuthenticate enabled can't refresh expired password
4 participants