Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure API SharedKeyLite in Powershell

I'm trying to implement a SharedKeyLite Authorization header function in powershell. This is to connect to Azure Tables REST API. I'm missing something cause I keep getting an error:

Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

   function GenerateHeader($accountName, $accountKey, $action)
{
    $xmsdate = get-date
    $xmsdate = $xmsdate.ToUniversalTime()
    $xmsdate = $xmsdate.toString('r')
    $newLine = "`n";
    $message = $xmsdate + $newline + "/" + $accountname + "/" + $action;
    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
    $hmacsha.key = [Convert]::FromBase64String($accesskey)
    $signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($message))
    $signature = [Convert]::ToBase64String($signature)
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("x-ms-version", "2014-02-14")
    $headers.Add("x-ms-date", $xmsdate)
    $headers.Add("Authorization", "SharedKeyLite " + $accountName + ":" + $signature)

    return $headers
}

UPDATE: Here's code that calls this function. The $action variable is set to the URI string.

$uriString = "https://$StorageAccountName.table.core.windows.net/Tables"

$headers = GenerateHeader $StorageAccountName $StorageAccountKey "Tables"

Invoke-RestMethod -Uri $uriString -Method $method -Headers $headers -Body $body

And here's the error it throws.

Invoke-RestMethod : AuthenticationFailedServer failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:4215377d-0002-0044-1a92-94cd56000000 Time:2015-05-22T13:21:53.5205261Z At C:\Users\Samuel\Source\BaseDataInstall\BaseDataInstall\AzureHelpers.ps1:45 char:2 + Invoke-RestMethod -Uri $uriString -Method $method -Headers $headers -Body $body + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc eption + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

EDIT: Here's the Example output from the $headers variable outside the function...

Key   : x-ms-version
Value : 2014-02-14

Key   : x-ms-date
Value : Tue, 26 May 2015 19:30:20 GMT

Key   : Authorization
Value : SharedKeyLite <MyStorageName>:lf+ndqhi4OeJhIfLljugT0dfcLbqXDBHwrQJn9Q66HQ=
like image 289
SamuelWarren Avatar asked May 21 '15 21:05

SamuelWarren


People also ask

How do I run Azure API in PowerShell?

To use the Azure Rest API using PowerShell, we first need to connect to the Azure cloud account using the Connect-AzAccount. Once you are connected to the Azure Account, you can use the below authorization header (same has been provided on the MS website) which contains a bearer token to authenticate the rest API.

What is Azure table storage?

Azure Table storage is a service that stores non-relational structured data (also known as structured NoSQL data) in the cloud, providing a key/attribute store with a schemaless design. Because Table storage is schemaless, it's easy to adapt your data as the needs of your application evolve.


2 Answers

So this ended up being a simple coding error :(

I feel kinda silly posting this now, but I'm going to post an answer cause I couldn't find a working Authorization builder for Azure in Powershell anywhere. This one does work for Azure tables...

function GenerateHeader($accountName, $accountKey, $action)
{
    $xmsdate = get-date
    $xmsdate = $xmsdate.ToUniversalTime()
    $xmsdate = $xmsdate.toString('R')
    $newLine = "`n";
    $action = $action.ToLower()
    $message = $xmsdate + $newline + "/" + $accountname + "/" + $action;
    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
    $hmacsha.key = [Convert]::FromBase64String($accountKey)
    $signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($message))
    $signature = [Convert]::ToBase64String($signature)
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Content-Type", "application/json")
    $headers.Add("x-ms-date", $xmsdate)
    $headers.Add("Authorization", "SharedKeyLite " + $accountName + ":" + $signature)

    return $headers
}
like image 127
SamuelWarren Avatar answered Oct 07 '22 20:10

SamuelWarren


There seem to be a change in the Azure API. I had to disable the "toLower" statement for this to Work.

function GenerateHeader($accountName, $accountKey, $action)
{
    $xmsdate = get-date
    $xmsdate = $xmsdate.ToUniversalTime()
    $xmsdate = $xmsdate.toString('R')
    $newLine = "`n";
    # $action = $action.ToLower()
    $message = $xmsdate + $newline + "/" + $accountname + "/" + $action;
    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
    $hmacsha.key = [Convert]::FromBase64String($accountKey)
    $signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes ($message))
    $signature = [Convert]::ToBase64String($signature)
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    # $headers.Add("Content-Type", "application/json")
    $headers.Add("x-ms-date", $xmsdate)
    $headers.Add("Authorization", "SharedKeyLite " + $accountName + ":" + $signature)

    return $headers
}

I hope this helps someone :-)

like image 21
Jan Jørgensen Avatar answered Oct 07 '22 20:10

Jan Jørgensen