Skip to content
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

PAT authentication failing with Azure Devops on premise Artifacts feed #1593

Open
3 tasks done
gerryleys opened this issue Mar 11, 2024 · 4 comments
Open
3 tasks done
Labels
Area-Install Issue-Bug Something isn't working

Comments

@gerryleys
Copy link
Contributor

Prerequisites

  • Write a descriptive title.
  • Make sure you are able to repro it on the latest released version
  • Search the existing issues.

Steps to reproduce

Access to onprem Azure Devops Artifacts feed failed when authenticating using a PAT token, created by Azure Devops.

$Token = "...TOKEN..." | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential('PAT', $Token)
Set-Secret -Name AzureArtifactToken -Secret $Credential
$CredentialInfo = New-Object Microsoft.PowerShell.PSResourceGet.UtilClasses.PSCredentialInfo ("MySecrets", "AzureArtifactToken")

$Params = @{
Name = 'RepoName'
Uri = 'https://mydomain.org/org/grp/_packaging/grp/nuget/v3/index.json'
Trusted = $true
CredentialInfo = $CredentialInfo
ApiVersion = 'v3'
}
Set-PSResourceRepository @params

After examine this issue further, we found out that the API server calls were performed by a HttpClient class method, using 'negotiate' authentication by default (in our situation). As the PAT token in the SecretStore is retreived as a PSCredential, PSResourceGet passes this PAT token as a 'NetworkCredential' to the ServerApiCalls class methods (incl. v3).

        HttpClientHandler handler = new HttpClientHandler()
        {
            AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
            Credentials = networkCredential
        };

But, a PAT token requires 'Basic authentication' to succeed. See https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#use-a-pat-in-your-code. To test this, I modified the API calls (incl. V3) with a token detection (username = 'PAT') and added a HttpClient AuthenticationHeader with Basic authentication. After rebuilding and testing this code, the Authentication was successful!

    public ServerApiCall(PSRepositoryInfo repository, NetworkCredential networkCredential)
    {
        this.Repository = repository;
        
        HttpClientHandler handler = new HttpClientHandler();
        bool token = false;

        if(networkCredential != null) 
        {
            if (String.Equals("PAT", networkCredential.UserName))
            {
                token = true;
            } 
        };

        if (token)
        {
            string credString = string.Format(":{0}", networkCredential.Password);
            byte[] byteArray = Encoding.ASCII.GetBytes(credString);

            _sessionClient = new HttpClient(handler);
            _sessionClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

        } else {

            handler.Credentials = networkCredential;
            
            _sessionClient = new HttpClient(handler);
        };
    }

Expected behavior

Find-PSResource -> list of requested packages

Actual behavior

Find-PSResource: 'Response status code does not indicate success: 401 (Unauthorized).' Re-run the command with -Credential.

Error details

No response

Environment data

ModuleType Version    PreRelease Name                                ExportedCommands
---------- -------    ---------- ----                                ----------------
Binary     1.0.2                 Microsoft.PowerShell.PSResourceGet  {Find-PSResource, Get-InstalledPSResource, Get-PSResourceRepository, Get-PSScriptFileInfo…}

Key   : PSVersion
Value : 7.3.2
Name  : PSVersion


Key   : PSEdition
Value : Core
Name  : PSEdition


Key   : GitCommitId
Value : 7.3.2
Name  : GitCommitId


Key   : OS
Value : Microsoft Windows 10.0.14393
Name  : OS


Key   : Platform
Value : Win32NT
Name  : Platform


Key   : PSCompatibleVersions
Value : {1.0, 2.0, 3.0, 4.0…}
Name  : PSCompatibleVersions


Key   : PSRemotingProtocolVersion
Value : 2.3
Name  : PSRemotingProtocolVersion


Key   : SerializationVersion
Value : 1.1.0.1
Name  : SerializationVersion


Key   : WSManStackVersion
Value : 3.0
Name  : WSManStackVersion

Visuals

No response

@SydneyhSmith
Copy link
Collaborator

Thanks @gerryleys for opening the issue and providing detailed steps-- we really appreciate it...looks like you have a good fix, would you be interested in contributing a PR? We are hoping to get out a patch release

@SydneyhSmith SydneyhSmith added Issue-Bug Something isn't working Area-Install and removed Needs-Triage labels Mar 11, 2024
@gerryleys gerryleys mentioned this issue Mar 13, 2024
14 tasks
@gerryleys
Copy link
Contributor Author

gerryleys commented Mar 13, 2024

@SydneyhSmith I created a PR. A small adaptation from the first suggested quick fix. I used the linked PS SecretStore secret with a 'SecureString' datatype object to be treated as a (PAT) token, this makes more sense. This translates later in the code to a PSCredential object with username 'token', and will be handled with 'Basic Authorization'.

@gerryleys
Copy link
Contributor Author

@SydneyhSmith Any news on this PR? Is there something I can do or modify? Thanks in advance.

@SydneyhSmith
Copy link
Collaborator

@gerryleys apologies for the delay, we have a few folks out on Spring Break and the rest at PowerShell Summit this week... I'll try to get a review on it in the next week

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Install Issue-Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants