microsoft / artifacts-credprovider

The Azure Artifacts Credential Provider enables dotnet, NuGet.exe, and MSBuild to interactively acquire credentials for Azure Artifacts feeds.
MIT License
771 stars 706 forks source link

dotnet list <SOLUTION> package --vulnerable/--outdated/--deprecated fails with Azure Artifacts Credential Provider #487

Closed josundt closed 1 month ago

josundt commented 7 months ago

Not sure if this is a NuGet or an Azure Artifacts Credentials Provider issue.

An issue has been created in the GitHub repository for the NuGet project: https://github.com/NuGet/Home/issues/13308

Refer to that issue for details.

embetten commented 7 months ago

@josundt - can you confirm the version of this cred provider you are using? We just pushed a new version 1.1.1 and it would be interesting to know if this behavior is isolated to a specific version of this cred provider.

josundt commented 7 months ago

@embetten I have tested upgrading the credential provider from v1.0.5 to v1.1.1. The exact same thing happens. When running dotnet list package --vulnerable in the folder of the solution file, it still fails with authentication failure 401 like before.

I believe this problem easily can be reproduced on your end.

FYI: If I also add the --interactive option to the command above, I'm prompted to authenticate (device flow) over and over for each project in the solution. If I authenticate each time I'm prompted, the command eventually gives the expected result/output.

But then if I run the exact same command again, I need to authenticate all over again, once for each project in the solution. It looks like tokens do not get properly persisted on the device in the scenario I have described.

pkamphuis commented 6 months ago

I am experiencing the same issue. credential provider v1.1.1 and DotNet 8.0.203. macOS Monterey 12.7.4 I am also experiencing similar issue with the DotNet cli tooling on my work windows laptop. Nuget/package management works fine from Visual Studio.

For each triggered device flow authentication, a PAT token is created in Azure Devops. But the SessionTokenCache is never updated. Resulting in an repetitive sequence of authentication attempts

josundt commented 5 months ago

[ @embetten Is anything happning here? This problem is still not fixed and the the NuGet repository issue has also been closed with no proper fix. I have tested again with .NET 8.0.4 (SDK 8.0.204), and this fails just the same.

Can you please investigate this further?

How to reproduce

You need:

In a terminal with the solution folder as the current working directory, do as follows:

  1. To verify that you're properly authenticated and that the credential provider has acquired and stored a valid token, run dotnet restore --interactive. If the credential provider had no valid token in store from ealier, a device flow authentication procedure will start. If this happens, please complete the authentication. The credential provider now has a valid token stored.
  2. Run dotnet restore -f. Since you have a valid token stored after completing 1), this should work without any need for reauthentication.
  3. Run dotnet list package --vulnerable. Even if we after 1) should have a valid token, the command fails with 401 Not authenticated responses, as if the list package command does not find/include the token acquired in 1) in the HTTP requests.

After the command failure in 3), any stored token also seem to be deleted, so if you try running the command in 2) again after 3), it will also return in 401 Not Authenticated responses as if you have never authenticated before.

If you now try to add the --interactive parameter to the command in 3), it will start device flow authentication for each of the projects in the solution, but even if you complete all these, no token gets stored and it will not work. ](https://github.com/microsoft/artifacts-credprovider/issues/487)

embetten commented 4 months ago

I finally have a repro on a non-windows machine - but it is not consistent.

I see the session token cache is not consistently updated after device code flow, but this was interestingly transient on MacOs. When the credprovider's session token cache is not updated after device code flow, I also noticed the msal cache is not getting set either. If the MSAL cache was getting set, then we would not be running into issues as subsequent calls would invoke MSAL silent to pick up the msal cache token. So this might be an issue in MSAL as well? will continue digging in here

As a workaround, if you have access to a browser, you might be able to get around this by forcing interactive auth which reliably sets the cache by setting the env variable NUGET_CREDENTIALPROVIDER_FORCE_CANSHOWDIALOG_TO to true. Otherwise, device code flow will be needed for every call :(

embetten commented 4 months ago

[ @embetten Is anything happning here? This problem is still not fixed and the the NuGet repository issue has also been closed with no proper fix. I have tested again with .NET 8.0.4 (SDK 8.0.204), and this fails just the same.

Can you please investigate this further?

How to reproduce

You need:

  • An Azure DevOps-hosted NuGet feed
  • The latest Azure Artifacts Credential Provider for .NET installed.
  • A VS solution (.sln) containing a few C# projects (.csproj) in (separate subfolders for each project). (In my case: a Web API project with project references to two class library projects).
  • A nuget.config file in the solution folder with the before mentioned Azure DevOps-hosted NuGet feed added as a source.
  • Package dependencies (PackageReference) to packages hosted in the Azure DevOps-hosted NuGet feed in the C# projects.

In a terminal with the solution folder as the current working directory, do as follows:

  1. To verify that you're properly authenticated and that the credential provider has acquired and stored a valid token, run dotnet restore --interactive. If the credential provider had no valid token in store from ealier, a device flow authentication procedure will start. If this happens, please complete the authentication. The credential provider now has a valid token stored.
  2. Run dotnet restore -f. Since you have a valid token stored after completing 1), this should work without any need for reauthentication.
  3. Run dotnet list package --vulnerable. Even if we after 1) should have a valid token, the command fails with 401 Not authenticated responses, as if the list package command does not find/include the token acquired in 1) in the HTTP requests.

After the command failure in 3), any stored token also seem to be deleted, so if you try running the command in 2) again after 3), it will also return in 401 Not Authenticated responses as if you have never authenticated before.

If you now try to add the --interactive parameter to the command in 3), it will start device flow authentication for each of the projects in the solution, but even if you complete all these, no token gets stored and it will not work. ](#487)

Unless you run dotnet nuget locals all -c before the dotnet restore -f in step 2 will always succeed with or without cached credentials.

josundt commented 4 months ago

@embetten Valid point that my repro recipe would have been more correct if 2) was:

dotnet nuget locals all -c ...then... dotnet restore

I have therefore updated my previous comment, so the repro steps are correctly described.

Hoping for the issue to get fixed as soon as possible 👍

github-actions[bot] commented 1 month ago

This issue has had no activity in 90 days. Please comment if it is not actually stale.

josundt commented 1 month ago

@embetten FYI: This one is seemingly solved in one of the latest SDK (8.0.3*) updates and can be closed.

embetten commented 1 month ago

closing due to fix in dotnet