PowerShell / PowerShell/PSResourceGet
PAT authentication failing with Azure Devops on premise Artifacts feed
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 576
- Forks
- 114
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 7
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Begin at the ServerApiCall constructor and its HttpClientHandler setup described in the report; trace the v3 API path and credential handling. Verify that Find-PSResource against the on-premise Azure DevOps feed succeeds with the PAT while ordinary credentials retain their existing behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, csharp, powershell
- Domain
- api, authentication, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100