Using PowerShell to retrieve an auth token for a set of APIs. The endpoint requires several headers, including a "secret", "id1", and "id2" among others.
How to include the secret in the header as SecureString
, or other such format that similarly protects it?
Code works when $secret
is a plain old String
type.
function Invoke-RestCall
{
param
(
[Guid]$id1,
[string]$id2
[Security.SecureString]$clientSecret,
#... other parameters for other headers
)
$uri = "https://..." #uri removed for public SO posting
$headers = @{}
$headers.Add("X-Id1", $id1)
$headers.Add("X-Id2", $id2)
$headers.Add("X-Secret", $clientSecret) # <-- how to convert from secure format?
# other headers go here
$response = Invoke-RestMethod -Uri $uri -Method GET -Headers $headers
$response | ConvertTo-Json
}
A simple attempt at converting the secret to an encrypted string, such as
$headers.Add("X-Secret", (ConvertFrom-SecureString -Key $secret))
causes the call to return 400 Bad Request.
SecureString
seems to be the most intuitive type to use. It's been a while since I worked with PowerShell so I'm not familiar with all the options. PSCredential
and NetworkCredential
seems like overkill but I'm still learning how to properly use them.
To decrypt the secure string, in Windows PowerShell 5.1 you can use:
[System.Net.NetworkCredential]::new('', $clientSecret).Password
Or if you have PowerShell 7+ you can also use:
$clientSecret | ConvertFrom-SecureString -AsPlainText
Ideally, if your API supports more robust authentication methods you shouldn't use this one, but that's up to the API.
Here is how you can structure your function:
function Invoke-RestCall {
param (
[Guid] $id1,
[string] $id2,
[securestring] $clientSecret,
[uri] $uri = "https://...",
[Microsoft.PowerShell.Commands.WebRequestMethod] $Method = 'GET'
#... other parameters for other headers
)
$requestParams = @{
Method = $Method
Uri = $uri
Headers = @{
"X-Id1" = $id1
"X-Id2" = $id2
"X-Secret" = [System.Net.NetworkCredential]::new('', $clientSecret).Password
}
}
# if you want the plain Json, use `Invoke-WebRequest` instead of `Invoke-RestMethod`
(Invoke-WebRequest @requestParams).Content
}