Version Affected: 8.2 and higher
Overview
GitHub hosts C# and JavaScript SDKs for the SecureAuth Authentication API, but if you are implementing the API in a different language, or not using an SDK, it can help to see a working example. This article provides a PowerShell script that generates the Authorization header the API requires, useful for testing and demonstration purposes. PowerShell is also relatively easy to read and translate into other languages. See the Authentication API Guide for the full API reference.
Generating the Header
Update the variables near the top of the script — AppId, AppKey, Method, ResourceUri, and UriPrefix — to match your realm and the API call you want to make, then run the script in PowerShell:
# Generate-IdP-API-Authorization-Header-via-Powershell
# Copyright (c) 2018, SecureAuth
# All rights reserved.
# More information: https://docs.secureauth.com/2104/en/authentication-api-guide.html
# 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
The script prints the computed HMAC, the resulting Authorization header, the full set of request headers, and the API's response.
For more information, see the SecureAuth GitHub.
SecureAuth Knowledge Base Articles provide information based on specific use cases and may not apply to all appliances or configurations. Be advised that these instructions could cause harm to the environment if not followed correctly or if they do not apply to the current use case.
Customers are responsible for their own due diligence prior to utilizing this information and agree that SecureAuth is not liable for any issues caused by misconfiguration directly or indirectly related to SecureAuth products.
Comments
Please sign in to leave a comment.