-
Notifications
You must be signed in to change notification settings - Fork 701
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
fixes NuGet/Home #11210 CredentialService
incorrectly sets the value of isRetry
#4636
Conversation
@@ -90,7 +90,7 @@ public CredentialService(AsyncLazy<IEnumerable<ICredentialProvider>> providers, | |||
cancellationToken.ThrowIfCancellationRequested(); | |||
|
|||
var retryKey = RetryCacheKey(uri, type, provider); | |||
var isRetry = _retryCache.ContainsKey(retryKey); | |||
var isRetry = (type == CredentialRequestType.Forbidden) && _retryCache.ContainsKey(retryKey); |
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.
Could you help me understand why Forbidden
and not Unauthorized
?
Forbidden suggests the username&password or PAT is valid, so no amounts of retries are going to succeed until permissions are fixed server side. The edge case is when the customer has two or more accounts, and they entered the wrong one.
Unauthorized suggests the username& password or PAT is invalid, so valid credentials need to be supplied in the retry.
Honestly, my intuition is that both attempts are a kind of retry, but only unauthorized responses make sense to retry. Why shouldn't incorrect credentials being supplied be treated as a retry?
My understanding of the problem, from reading the link issues, is that NuGet doesn't attempt to pass the credentials on the first HTTP request (same as how web browsers (usually?) don't, but NuGet incorrectly detects the first attempt at sending credentials as a retry. My gut feeling is that we need a more sophisticated fix, rather than treating all unauthorized responses as not-retries.
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.
My understanding of the problem, from reading the link issues, is that NuGet doesn't attempt to pass the credentials on the first HTTP request (same as how web browsers (usually?) don't, but NuGet incorrectly detects the first attempt at sending credentials as a retry.
The credential service should only come in play with a challenge, so I don't imagine we have an unneeded isRetry.
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.
I'm having a tough time figuring out the effects of this change here.
In particular I was reading:
dotnet/templating#4278 (comment)
Which suggests NuGet tries to talk to the provider after it's obtained successful credentials, which seems to contradict what
NuGet.Client/src/NuGet.Core/NuGet.Protocol/HttpSource/HttpSourceAuthenticationHandler.cs
Line 67 in 5ac4851
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) |
If NuGet retries for successful credentials then this wouldn't fix it correct?
Can you maybe explain step by step what happens here currently and what should be happen with a focus on what the customer sees.
} | ||
|
||
[Fact] | ||
public async Task GetCredentialsAsync_SecondCallHasRetryTrue_WhenTypeIsForbidden() |
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.
I'd flip the 2nd and 3rd part of the name here. https://github.com/NuGet/NuGet.Client/blob/dev/docs/coding-guidelines.md#unit-test-method-naming
@@ -90,7 +90,7 @@ public CredentialService(AsyncLazy<IEnumerable<ICredentialProvider>> providers, | |||
cancellationToken.ThrowIfCancellationRequested(); | |||
|
|||
var retryKey = RetryCacheKey(uri, type, provider); | |||
var isRetry = _retryCache.ContainsKey(retryKey); | |||
var isRetry = (type == CredentialRequestType.Forbidden) && _retryCache.ContainsKey(retryKey); |
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.
My understanding of the problem, from reading the link issues, is that NuGet doesn't attempt to pass the credentials on the first HTTP request (same as how web browsers (usually?) don't, but NuGet incorrectly detects the first attempt at sending credentials as a retry.
The credential service should only come in play with a challenge, so I don't imagine we have an unneeded isRetry.
I attempted to do fix explained in NuGet/Home#11210 My understanding of what is happening:
As the result, the user need to authenticate twice on installing / updating template packages with Proper fix might be:
This will avoid the need of re-authentication. But this will need changes in API, I cannot see any way how 2nd try is possible with existing definition of Another way is to share |
A problem that the Is it possible that |
Yes, it appears it does, thank you for pointing it out - |
We recently fixed a similar issue with list package: NuGet/Home#11169. |
So this worked perfectly, so dotnet/templating issue will be fixed in dotnet/templating#4764. I don't have enough context to see if NuGet/Home#11210 should be closed too. It's clear that fix suggested in that issue won't work. |
Bug
fixes NuGet/Home#11210
Related to: dotnet/templating#4278
Description
Fixed setting of
isRetry
value inCredentialService
,isRetry
should be set only when previous request fails.This affects the UX of .NET SDK as users need to auth multiple times when doing operations with private NuGet feed.
isRetry
should not be set on subsequent call unless the credentials are invalid.PR Checklist
PR has a meaningful title
PR has a linked issue.
Described changes
Tests
Documentation