chocolatey / choco

Chocolatey - the package manager for Windows
https://chocolatey.org
Other
10.26k stars 901 forks source link

Would it be possible to add Credential Provider support? #1721

Open moikot opened 5 years ago

moikot commented 5 years ago

NuGet 3 and later supports the Credential Provider, which automatically acquires feed credentials when needed but Chocolatey still uses v2.

I'm especially interested in CredentialProvider.Vss.exe support since I'm hosting my Chocolatey packages on internal Azure DevOps feeds.

I know that I can:

  1. Use PAT and V2 but it's super cumbersome for the users. First, they have to obtain a token and then use it by adding to the config file or explicitly in the commands.

  2. Wrap choco calls into a custom command line tool which could call CredentialProvider.Vss.exe first and then call choco.exe with the JWT obtained. But again, it looks like a workaround.

ferventcoder commented 5 years ago

We are looking to move to v3+ this year (hopefully, barring any further issues). So that should be able to bring this with it.

ferventcoder commented 5 years ago

Related to #508

asklar commented 4 years ago

@ferventcoder any updates on this? I have a nupkg hosted on an internal authenticated server and I can access it through nuget but not through choco

t0ralf commented 4 years ago

Yep, I'm also looking for a solution to this problem. Would be great if choco can offer that

tapika commented 3 years ago

Btw, by default nuget asks for credentials, but nuget saved token is valid for 4 hours. (Seriously Microsoft ? Seriously ???) Personal authentication token is valid for 1 year.

Maybe using credentials provider is not worth of effort of implementing it.

tapika commented 3 years ago

After couple of debug sessions on https://github.com/microsoft/artifacts-credprovider - I've realized that you need to use netfx version to get UI prompt and special environment variable to suppress device credential prompt (visit url, seriously ?)

Attaching here whole code to be able to authorize nuget and choco feeds.

For choco feed you will need either my patch or reconfigure choco manually.

Here is whole powershell example if anyone cares to use it.

Generated personal authentication token should be valid for 1 year, but that value can be extended - I've managed to get even for 5 years. (From web page it's not possible)

param (
    [Parameter(Mandatory=$true)]
    [string]$feedName,

    [Parameter(Mandatory=$true)]
    [string]$url
)

$profilePath = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile)
$pluginLocation = [System.IO.Path]::Combine($profilePath, ".nuget", "plugins");
$localNetfxCredProviderPath = [System.IO.Path]::Combine("netfx", "CredentialProvider.Microsoft");
$fullNetfxCredProviderPath = [System.IO.Path]::Combine($pluginLocation, $localNetfxCredProviderPath)
$netfxExists = Test-Path -Path ($fullNetfxCredProviderPath)

if($netfxExists -eq $false)
{
    Write-Host "Installing credential provider..."
    iex "& { $(irm https://aka.ms/install-artifacts-credprovider.ps1) } -AddNetfx"

    $netfxExists = Test-Path -Path ($fullNetfxCredProviderPath)
    if($netfxExists -eq $false)
    {
        Write-Host "Credentials provider is required."
        Write-Host "Maybe install manually from https://github.com/microsoft/artifacts-credprovider/releases"
        return
    }
}

$exe = [System.IO.Path]::Combine($fullNetfxCredProviderPath, 'CredentialProvider.Microsoft.exe')
# It's not possible to disable device based authentication, but we can set timeout to fail immidiately.
$ENV:NUGET_CREDENTIALPROVIDER_VSTS_DEVICEFLOWTIMEOUTSECONDS=0
# Validity period: 1 year. (Can have larger value)
$ENV:NUGET_CREDENTIALPROVIDER_VSTS_SESSIONTIMEMINUTES=365*24*60
# '-V Error' is required not to get extra messages
$msg = & $exe -V Error -U $url -C -F JSON 2>&1 | Out-String

if($lastexitcode -ne 0)
{
    Write-Host
    Write-Host "$msg"
    Write-Host
    Write-Host "Failed to run '$exe' ($lastexitcode)"
    return
}

try
{
    $info = ConvertFrom-Json $msg
}
catch
{
    Write-Host
    Write-Host "$msg"
    Write-Host
    return
}

# $info.Password

$nugetConfig = [System.Environment]::ExpandEnvironmentVariables("%APPDATA%\NuGet\nuget.config")

$nuget = '.\nuget.exe'

$msg = & $nuget sources remove -name $feedName -config $nugetConfig 2>&1 | Out-String

& $nuget sources add -name $feedName -source $url -username MyOwnPat -password $info.Password -StorePasswordInClearText -config $nugetConfig 2>&1
tapika commented 3 years ago

Btw

https://devblogs.microsoft.com/devops/new-personal-access-token-lifecycle-apis-in-private-preview/

there exists also API to create personal access tokens - but what I've briefly tested - it did not work for me.

Meanwhile - CredentialProvider.Microsoft.exe can create PAT out of box. It's usage however is limited to packaging read/write.

padillah commented 1 year ago

Is there any update on this? We are trying to use chocolatey but we don't want to use PAT. Is anyone making progress with this?

TheCakeIsNaOH commented 1 year ago

@padillah look at the issue labels for the status of an issue. Specifically, this issue is still in triaging, so it is undecided if this feature would be added to Chocolatey CLI.

As for this issue specifically, #508 was completed, and will be release with v2.0.0 of Chocolatey CLI. So this issue would then be unblocked and potentially could be added in a release after v2.0.0, as #508 is a prerequisite for this feature.

padillah commented 1 year ago

You'll have to forgive me for wondering if something that hasn't had so much as a comment in two years may have fallen by the wayside. Thank you.

mgrandi commented 1 year ago

what is left to complete this? i am interested in working on this

TheCakeIsNaOH commented 1 year ago

@mgrandi you will probably want to look at https://github.com/chocolatey/choco/blob/develop/src/chocolatey/infrastructure.app/nuget/NugetCommon.cs and https://github.com/chocolatey/choco/blob/develop/src/chocolatey/infrastructure.app/nuget/ChocolateyNugetCredentialProvider.cs As those are the locations where Chocolatey CLI sets up credentials for sources. I don't know if additional credential providers should be added via additional logic into ChocolateyNugetCredentialProvider, or as additional ICredentialProviders passed into the NuGet libraries.

Given that Chocolatey CLI uses the NuGet Client libraries, it may help to look at the different implementations of ICredentialProvider to see how NuGet.exe uses them. https://github.com/chocolatey/NuGet.Client/blob/develop/src/NuGet.Core/NuGet.Credentials/ICredentialProvider.cs

Some thought and discussion probably needs to go into how additional providers are added/configured/enabled/disabled/installed/discovered/etc. I don't know enough about them to really have an option yet.

Also, given that this issue is still under triaging, a PR may not be accepted if the Chocolatey team determines this is outside the scope of what should be added to Chocolatey CLI.