Reputation: 511
I'm using a private NuGet feed through Azure DevOps.
To see information about a public NuGet package from code, one simply has to follow the documentation here.
In particular:
ILogger logger = NullLogger.Instance;
CancellationToken cancellationToken = CancellationToken.None;
SourceCacheContext cache = new SourceCacheContext();
SourceRepository repository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json");
PackageMetadataResource resource = await repository.GetResourceAsync<PackageMetadataResource>();
IEnumerable<IPackageSearchMetadata> packages = await resource.GetMetadataAsync(
"Newtonsoft.Json",
includePrerelease: true,
includeUnlisted: false,
cache,
logger,
I'm trying to achieve the same result for my own private feed by adding my credentials to the process:
var logger = NullLogger.Instance;
var cancellationToken = CancellationToken.None;
var cache = new SourceCacheContext();
var source = new PackageSource("*my feed*/nuget/v3/index.json");
source.Credentials = new PackageSourceCredential("*my feed*/nuget/v3/index.json", "*username*", "*password*", true, null);
var repository = Repository.Factory.GetCoreV2(source);
var resource = await repository.GetResourceAsync<PackageMetadataResource>();
IEnumerable<IPackageSearchMetadata> searchMetadata = await resource.GetMetadataAsync(
"My.Package.Name",
includePrerelease: true,
includeUnlisted: false,
cache,
logger,
cancellationToken);
Please note, that even though I call the Factory.GetCoreV2()
, the inside of the method still calls V3 providers. It's simply the only constructor that takes a PackageSource as a parameter:
public static SourceRepository GetCoreV2(this Repository.RepositoryFactory factory, PackageSource source)
{
return Repository.CreateSource(Repository.Provider.GetCoreV3(), source);
}
However, no matter what I do, I cannot get through step
var resource = await repository.GetResourceAsync<PackageMetadataResource>();
which keeps failing with a NuGet.Protocol.Core.Types.FatalProtocolException - 401 Unauthorised
. I've verified the validity of my credentials and my feed endpoint, as well as my permissions within the feed (full access). I've also tried the initialisation process described here (plus the step with my credentials), yet the result is the same.
How am I expected to identify to an Azure DevOps feed from code, to be able to get the IPackageMetadata information?
Upvotes: 3
Views: 2847
Reputation: 13468
An alternative route to managing secure DevOps package feeds is to use the DevOps REST API https://learn.microsoft.com/en-us/rest/api/azure/devops/artifacts/feed%20%20management/get%20feeds?view=azure-devops-rest-6.0
There does not appear to be a package that interfaces to this API that I could see so I created a very simple library that uses a few of the REST API methods
https://github.com/conficient/DevOpsNugetClient
I used this to successfully query and delete several hundred redundant packages and related versions on our internal feed.
Upvotes: 3
Reputation: 53
I dug a little deeper and it does seem to be possible, please see this Gist with an example implementation https://gist.github.com/cpyfferoen/74092a74b165e85aed5ca1d51973b9d2
Upvotes: 3
Reputation: 15096
Azure DevOps doesn't support username & password authentication through NuGet. If your account needs 2 factor authentication (2FA), there's no way for NuGet to prompt you for it. I don't know if they decided not to support it for all accounts, even ones that are not 2FA enabled, or if there are other reasons as well (I suspect it's not allowed for other security reasons).
If you have Visual Studio installed, or have otherwise installed the Azure Artifacts NuGet credentials provider, maybe you could try not using any credentials in your code. I'm not sure how exactly nuget.exe, dotnet cli and msbuild discover the credentials provider, but maybe it works when using the sdk as well.
Otherwise if you want to, or need to, use the credentials API, you need to generate a personal access token, and use that as the password.
Upvotes: 3