Skip to content

Commit

Permalink
Fix NuGet/Home#1158: Basic auth issues with NuGet 3.1.1 in Visual Stu…
Browse files Browse the repository at this point in the history
…dio 2015.

Note that this issue is related to NuGet/Home#941 (Package restore of universal applications does not work with authenticated feeds).
It was closed as fixed but the fix misses two scenarios:
- The credentials saved in nuget.config is not used.
- The Prompt dialog will not pop up again if user gives the wrong credentials.
  • Loading branch information
feiling committed Aug 20, 2015
1 parent d56b011 commit fc808c4
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 33 deletions.
39 changes: 17 additions & 22 deletions src/VsExtension/NuGetPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Globalization;
Expand Down Expand Up @@ -95,12 +96,14 @@ public sealed class NuGetPackage : Package, IVsPackageExtensionProvider, IVsPers
private NuGetSettings _nugetSettings;

private OutputConsoleLogger _outputConsoleLogger;
private HashSet<Uri> _credentialRequested;

public NuGetPackage()
{
ServiceLocator.InitializePackageServiceProvider(this);
StandaloneSwitch.IsRunningStandalone = false;
_nugetSettings = new NuGetSettings();
_credentialRequested = new HashSet<Uri>();
}

private IVsMonitorSelection VsMonitorSelection
Expand Down Expand Up @@ -342,9 +345,10 @@ private void SetDefaultCredentialProvider()
PackageSourceProvider packageSourceProvider = new PackageSourceProvider(
new SettingsToLegacySettings(Settings));
var visualStudioCredentialProvider = new VisualStudioCredentialProvider(webProxy);
HttpClient.DefaultCredentialProvider = new SettingsCredentialProvider(
var settingsCredentialProvider = new SettingsCredentialProvider(
visualStudioCredentialProvider,
packageSourceProvider);
HttpClient.DefaultCredentialProvider = settingsCredentialProvider;

// Set up proxy handling for v3 sources.
// We need to sync the v2 proxy cache and v3 proxy cache so that the user will not
Expand Down Expand Up @@ -382,30 +386,21 @@ private void SetDefaultCredentialProvider()

NuGet.Protocol.Core.v3.HttpHandlerResourceV3.PromptForCredentials = uri =>
{
var v2Credentials = v2CredentialStore?.GetCredentials(uri);
if (v2Credentials != null)
{
// if cached v2 credentials have not been used, try using it first.
return v2Credentials;
}
bool retrying = _credentialRequested.Contains(uri);

lock (_credentialsPromptLock)
// Add uri to the hashset so that the next we know the credentials for this
// uri has been requested before. In this case, a dialog will pop up asking
// for credentials.
if (!retrying)
{
// Retry after we acquire the lock. The credential provider could have been updated while
// we were waiting to acquire it.
v2Credentials = v2CredentialStore?.GetCredentials(uri);
if (v2Credentials != null)
{
// if cached v2 credentials have not been used, try using it first.
return v2Credentials;
}

return visualStudioCredentialProvider.GetCredentials(
uri,
proxy: null,
credentialType: CredentialType.RequestCredentials,
retrying: false);
_credentialRequested.Add(uri);
}

return settingsCredentialProvider.GetCredentials(
uri,
proxy: null,
credentialType: CredentialType.RequestCredentials,
retrying: retrying);
};

NuGet.Protocol.Core.v3.HttpHandlerResourceV3.CredentialsSuccessfullyUsed = (uri, credentials) =>
Expand Down
19 changes: 8 additions & 11 deletions src/VsExtension/VisualStudioCredentialProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,18 @@ public ICredentials GetCredentials(Uri uri, IWebProxy proxy, CredentialType cred
{
// The cached credentials that we found are not valid so let's ask the user
// until they abort or give us valid credentials.

// Set the static property WebRequest.DefaultWebProxy so that the right host name
// is displayed in the UI by IVsWebProxy.
var uriToDisplay = uri;
if (credentialType == CredentialType.ProxyCredentials)
if (credentialType == CredentialType.ProxyCredentials && proxy != null)
{
if (proxy != null)
{
// Display the proxy server's host name when asking for proxy credential
uriToDisplay = proxy.GetProxy(uri);
}

WebRequest.DefaultWebProxy = new WebProxy(uriToDisplay);
// Display the proxy server's host name when asking for proxy credentials
uriToDisplay = proxy.GetProxy(uri);
}

// Set the static property WebRequest.DefaultWebProxy so that the right host name
// is displayed in the UI by IVsWebProxy. Note that this is just a UI thing,
// so this is needed no matter wether we're prompting for proxy credentials
// or request credentials.
WebRequest.DefaultWebProxy = new WebProxy(uriToDisplay);
return PromptForCredentials(uri);
}
finally
Expand Down

0 comments on commit fc808c4

Please sign in to comment.