# Generate-IdP-API-Authorization-Header-via-Powershell # Copyright (c) 2018, SecureAuth # All rights reserved. # More information: https://docs.secureauth.com/display/91docs/Authentication+API+Guide # Variables $IdPVersion92orHigher = $True # Set to FALSE for IdP 9.1 and lower $AppId = '4068954873794549a4acb0569aaf5af5' # Change to use your AppId $AppKey = '4c58595befbe30e40b661a46f554bee9dc3dbcdc8c5ad916dbc4eadf8f8e6183' # Change to use your AppKey $Method = 'GET' $ResourceUri = '/secureauth82/api/v1/users/user1/factors' # Change the realm number to the realm you are using, and user1 to the user account you want to test with $UriPrefix = 'https://idp.secureauthlab.com' # Change FQDN to match your IdP's FQDN If($IdPVersion92orHigher){$RequestDate = (Get-Date).ToUniversalTime().ToString('ddd, dd MMM yyyy HH:mm:ss.fff') + " GMT"} Else{$RequestDate = (Get-Date).ToUniversalTime().ToString('ddd, dd MMM yyyy HH:mm:ss') + " GMT"} # Functions function Test-Json { <# .SYNOPSIS Tests if a string is in valid JSON format .DESCRIPTION Test-Json takes an input string and tests for JSON validity. .PARAMETER InputString String to be evaluated for JSON format. .OUTPUTS Boolean True if Input string is valid JSON #> param ( $InputString ) try { $TempObject = ConvertFrom-Json $InputString -ErrorAction Stop; $IsJson = $true } catch { $IsJson = $false } return $IsJson } function Convert-HexToByte-HexString { <# .SYNOPSIS Converts a Hex string into a byte array .DESCRIPTION Convert-HexToByte-HexString takes a hex number string and converts each 2 hex characters into a single byte within an array of bytes. .PARAMETER HexString Hex string to be converted. Must be an even number of hex values. .OUTPUTS byte[] .EXAMPLE Convert-HexToByte-HexString -HexString '4c58595befbe30e40b661a46f554bee9dc3dbcdc8c5ad916dbc4eadf8f8e6183' #> param ( [string]$HexString ) $numberChars=$HexString.Length; [byte[]]$keyBytes=New-Object byte[] 32 for([int]$i=0;$i-lt$numberChars;$i=$i+2) { $keyBytes[$i/2]=[Convert]::ToByte($HexString.Substring($i,2),16); } return $keyBytes; } function New-SecureAuthAuthorizationHeader { <# .SYNOPSIS Builds a SecureAuth REST API authorisation header. .DESCRIPTION New-SecureAuthAuthorizationHeader takes 5 mandatory parameters with an optional request body and produces an authorization header that can be used with the SecureAuth API. .PARAMETER AppId Hex string containing the Application ID as configured on the IdP realm .PARAMETER AppKey Hex string containing the Application Key as configured on the IdP realm .PARAMETER ResourceUri The URI to the API end point. This should not contain the protocol or the FQDN of the IdP but the part of the URL immediately following. .PARAMETER RequestDate String containing the request datetime in GMT. Format for IdP version 9.2+ should include milliseconds: ddd, dd MMM yyyy HH:mm:ss.fff plus a space then "GMT" for IdP v9.2+ e.g.: Mon, 17 Dec 2018 11:51:30.934 GMT Format for 9.1 and lower should omit milliseconds: ddd, dd MMM yyyy HH:mm:ss plus a space then "GMT" e.g.: Mon, 17 Dec 2018 11:51:30 GMT .PARAMETER Method The HTTP Method being used, must be one of 'GET','POST', 'PUT' or 'DELETE'. Must be Uppercase. .PARAMETER RequestBody The request body in JSON format #> param ( [Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string]$AppId, [Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string]$AppKey, [Parameter(Mandatory=$true)][Uri]$ResourceUri, [Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string]$RequestDate, [Parameter(Mandatory=$true)][ValidateSet('GET','POST', 'PUT', 'DELETE')]$Method, [Parameter(Mandatory=$false)]$RequestBody ) begin { if([string]::IsNullOrEmpty($RequestBody)) { $hasBody=$false; } else { $hasBody=$true; } $appKeyByte=(Convert-HexToByte-HexString $AppKey); $dateString=$RequestDate } process { $pathstr = $ResourceUri if($hasBody) { if(Test-Json $RequestBody) { $RequestBodyJson = $RequestBody } else { $RequestBodyJson = $RequestBody | ConvertTo-Json -Compress } $message="$Method`n$dateString`n$AppId`n$pathstr`n$RequestBodyJson" } else { $message="$Method`n$dateString`n$AppId`n$pathstr" } write-host "`nMessage:`n$message" set-content -Path "c:\temp\hmac.txt" -Value $message $messageByte=[System.Text.Encoding]::UTF8.GetBytes($message); $hmacProvider=New-Object -TypeName 'System.Security.Cryptography.HMACSHA256'-ArgumentList @(,$appKeyByte); $hmac=[System.Convert]::ToBase64String($hmacProvider.ComputeHash($messageByte)); write-host "`nHMAC: $hmac" $headerValue="Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(("{0}:{1}"-f $AppId,$hmac))); return $headerValue; } } #Main # Build authorization header $authHeaderParams= @{ "AppId"=$AppId "AppKey"=$AppKey "Method"=$Method "ResourceUri"=$ResourceUri "RequestDate"=$RequestDate } $authHeader = New-SecureAuthAuthorizationHeader @authHeaderParams; Write-host "`nAuthorization Header: $authHeader" # Build headers if($IdPVersion92orHigher){ $headers = @{ 'Authorization' = $authHeader 'X-SA-Ext-Date' = $RequestDate 'Content-Type' = 'application/json' } } else{ $headers = @{ 'Authorization' = $authHeader 'X-SA-Date' = $RequestDate 'Content-Type' = 'application/json' } } write-host "`n`nHeaders:" $headers # Make HTTP request to API using created headers write-host "`n`n`nResponse:" -ForegroundColor Green $response = Invoke-RestMethod -Method $Method -Uri "$UriPrefix$ResourceUri" -Headers $headers | ConvertTo-Json -Depth 10 $response