Public/Invoke-IamAuthenticate.ps1

Import-Module powershell-jwt

<#
    .SYNOPSIS
    Authenticate agaist HSDP IAM as configured for the current Salesforce org

    .DESCRIPTION
    Uses the current org configuration to autenticate against the phecc__Access_Token_URL__c URL
    configured in the current configured Salesforce org.

    .INPUTS
    None. You cannot pipe objects to Invoke-IamAuthenticate.

    .OUTPUTS
    Returns as PSCustomObject with the following memebers:
        access_token
        expires_in
        refresh_token
        scope
        token_type

    .EXAMPLE
    PS> $auth = Invoke-IamAuthenticate

    .LINK
    Set-Config

    .NOTES
    Assumes config is initialized for org access.
#>

function Invoke-IamAuthenticate {

    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param()

    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
    }

    end {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }

    process {
        Write-Debug "[$($MyInvocation.MyCommand.Name)] PSBoundParameters: $($PSBoundParameters | Out-String)"

        $config = Get-Config
        $sfHsdpConfig = Get-SfHsdpConfig

        if ($config.ServiceKeyFile -and $config.ServiceAppId) {
            $uri = [System.Uri]$sfHsdpConfig.phecc__Access_Token_URL__c
            $aud = $uri.scheme + "://" + $uri.Authority + "/oauth2/access_token"
            $exp = [int](Get-Date -UFormat %s) + 5400
            $payloadClaims = @{
                "aud" = @($aud)
                "sub" = $config.ServiceAppId
            }
            $rsaPrivateKey = Get-Content $config.ServiceKeyFile -AsByteStream
            $jwt = New-JWT -Algorithm 'RS256' -Issuer $config.ServiceAppId -ExpiryTimestamp $exp -PayloadClaims $payloadClaims -SecretKey $rsaPrivateKey

            $Headers = @{
                "api-version"   = "1"
                "Content-Type"  = "application/x-www-form-urlencoded"
                "Accept"        = "application/json"
            }
            $Form = @{
                "grant_type"    = "urn:ietf:params:oauth:grant-type:jwt-bearer"
                "assertion"     = $JWT
            }
            $Uri = $sfHsdpConfig.phecc__Access_Token_URL__c
            Invoke-RestMethod -Uri $Uri -Method Post -Body $Form -Headers $Headers
        } else {
            $authForToken = [convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($sfHsdpConfig.phecc__Key__c):$($sfHsdpConfig.phecc__Secret__c)"))
            $Headers = @{
                "api-version"   = "2"
                "Content-Type"  = "application/x-www-form-urlencoded; charset=UTF-8"
                "Accept"        = "application/json"
                "Authorization" = "Basic $($authForToken)"
            }
            $Form = @{
                "grant_type" = "password"
                "username"   = $config.IamCredentials.GetNetworkCredential().username
                "password"   = $config.IamCredentials.GetNetworkCredential().password
                "scope"      = ($config.scopes -Join " ")
            }
            Invoke-RestMethod -Uri $sfHsdpConfig.phecc__Access_Token_URL__c -Method Post -Body $Form -Headers $Headers
        }
    }
}