- Created by Andreas Püschel, last modified on Jul 15, 2020
You are viewing an old version of this page. View the current version.
Compare with Current View Page History
« Previous Version 6 Next »
Scope
- Access to private Azure Blob Storage requires authentication.
- Shared Access Signatures (SAS) represent one of the authentication options.
Example
Download: azure_authentication_shared_access_signatures_sample.ps1
List, read and write blobs with Shared Access Signatures Expand source
# inspired by: # https://stackoverflow.com/questions/53653473/generating-an-sas-token-in-java-to-download-a-file-in-an-azure-data-storage-cont?rq=1 # https://docs.microsoft.com/en-us/rest/api/storageservices/create-account-sas#constructing-the-signature-string function Create-SASToken( [string] $Account, [string] $AccessKey, [string] $Version, [DateTime] $Now, [DateTime] $Expires, [string] $Permissions='r', $ResourceTypes='o', [string] $Services='b' ) { [Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null [string] $nowIso = (Get-Date (Get-Date $Now).ToUniversalTime() -Format "u").Replace( ' ', 'T' ) [string] $expiresIso = (Get-Date (Get-Date $Expires).ToUniversalTime() -Format "u").Replace( ' ', 'T' ) $stringToSign = $Account + "`n" ` + $Permissions + "`n" ` + $Services + "`n" ` + $ResourceTypes + "`n" ` + $nowIso + "`n" ` + $expiresIso + "`n" ` + "`n" ` + "https" + "`n" ` + $Version + "`n" $hmac = New-Object System.Security.Cryptography.HMACSHA256 $hmac.key = [Convert]::FromBase64String( $AccessKey ) $signature = $hmac.ComputeHash( [Text.Encoding]::UTF8.GetBytes( $stringToSign ) ) $signature = [Convert]::ToBase64String( $signature ) $sasToken = "sv=$Version" ` + "&ss=$Services" ` + "&srt=$ResourceTypes" ` + "&sp=$Permissions" ` + "&se=" + [System.Web.HttpUtility]::UrlEncode( $expiresIso ) ` + "&st=" + [System.Web.HttpUtility]::UrlEncode( $nowIso ) ` + "&spr=https" ` + "&sig=" + [System.Web.HttpUtility]::UrlEncode( $signature ) Write-Debug "now: $nowIso" Write-Debug "expires: $expiresIso" Write-Debug "stringToSign: $stringToSign" Write-Debug "sasToken: $sasToken" $signature, $sasToken } function Invoke-BlobRequest( [Uri] $Uri, [DateTime] $Now, [string] $Version, [string] $Method='GET', [string] $FilePath='' ) { $requestParams = @{} $requestParams.Add( 'Uri', $Uri ) $requestParams.Add( 'Method', $Method ) if ( $FilePath ) { $requestParams.Add( 'Infile', $FilePath ) } $requestParams.Add( 'Headers', @{ ` 'x-ms-blob-type' = 'BlockBlob'; ` 'x-ms-date' = "$(Get-Date (Get-Date $Now).ToUniversalTime() -Format 'R')"; ` 'x-ms-version' = $Version ` } ` ) Write-Debug ".... Invoke-WebRequest: $Uri" $requestParams.Keys | % { if ( $_ -eq 'Headers' ) { $item = $_ $requestParams.Item($_).Keys | % { Write-Debug "...... Headers $_ : $($requestParams.Item($item).Item($_))" } } else { Write-Debug "...... $_ $($requestParams.Item($_))" } } # run the web service request $response = Invoke-WebRequest @requestParams $response } # ---------- ---------- ---------- # Main # ---------- ---------- ---------- $ownerAccount = '<storage account>' $ownerAccessKey = '<storage account access key>' $requesterAccount = '<requester account>' $version = '2019-10-10' # consider badly synchronized server time and start 3 minutes in the past $now = (Get-Date).ToUniversalTime().AddMinutes(-3) # set the SAS token lifetime to 1 day $expires = $now.AddDays(1).ToUniversalTime() # consider the following values when creating SAS tokens # Permission: (r)ead, (w)rite, (d)elete, (l)ist # ResourceTypes: (o)bject, (c)ontainer, (s)ervice # Services: (b)lob, (q)ueue, (t)able, (f)ile Write-Host "`n" Write-Host "# ++++++++++++++++++++++++++++++" Write-Host "# Get Access Token" Write-Host "# ++++++++++++++++++++++++++++++" # step 1: create signature and SAS token for any operation (read, write, delete, list) on any resources (container, object) of the blob service $signature, $sasToken = Create-SASToken -Account $ownerAccount -AccessKey $ownerAccessKey -Version $version -Now $now -Expires $expires ` -Permissions 'rwdl' -ResourceTypes 'oc' -Services 'b' Write-Host "Signature: $signature" Write-Host "SAS Token: $sasToken" Write-Host "`n" Write-Host "# ++++++++++++++++++++++++++++++" Write-Host "# List Blobs in Container" Write-Host "# ++++++++++++++++++++++++++++++" <# # step 1: create signature and SAS token for list operation on container resources of the blob service $signature, $sasToken = Create-SASToken -Account $ownerAccount -AccessKey $ownerAccessKey -Version $version -Now $now -Expires $expires ` -Permissions 'l' -ResourceTypes 'c' -Services 'b' Write-Host "Signature: $signature" Write-Host "SAS Token: $sasToken" #> # step 2: send web service request $container = 'yade' $uri = "https://$($ownerAccount).blob.core.windows.net/$($container)?restype=container&comp=list" $response = Invoke-BlobRequest -Uri ($uri + "&" + $sasToken) -Now $now -Version $version -Method 'GET' Write-Host "Status Code: $($response.StatusCode)" Write-Host $response.Content Write-Host "`n" Write-Host "# ++++++++++++++++++++++++++++++" Write-Host "# Get Blob from Container" Write-Host "# ++++++++++++++++++++++++++++++" <# # step 1: create signature and SAS token for read operation on object resources of the blob service $signature, $sasToken = Create-SASToken -Account $ownerAccount -AccessKey $ownerAccessKey -Version $version -Now $now -Expires $expires ` -Permissions 'r' -ResourceTypes 'o' -Services 'b' Write-Host "Signature: $signature" Write-Host "SAS Token: $sasToken" #> # step 2: send web service request $container = 'yade' $blob = 'test.txt' $uri = "https://$($ownerAccount).blob.core.windows.net/$($container)/$($blob)" $response = Invoke-BlobRequest -Uri ($uri + '?' + $sasToken) -Now $now -Version $version -Method 'GET' Write-Host "Status Code: $($response.StatusCode)" Write-Host $response.Content Write-Host "`n" Write-Host "# ++++++++++++++++++++++++++++++" Write-Host "# Write Blob to Container" Write-Host "# ++++++++++++++++++++++++++++++" <# # step 1: create signature and SAS token for write operation on object resources of the blob service $signature, $sasToken = Create-SASToken -Account $ownerAccount -AccessKey $ownerAccessKey -Version $version -Now $now -Expires $expires ` -Permissions 'w' -ResourceTypes 'o' -Services 'b' Write-Host "Signature: $signature" Write-Host "SAS Token: $sasToken" #> # step 2: send web service request $container = 'yade' $filePath = "/tmp/some_blob.txt" $blob = (Get-Item $filePath).Name $uri = "https://$($ownerAccount).blob.core.windows.net/$($container)/$($blob)" $response = Invoke-BlobRequest -Uri ($uri + '?' + $sasToken) -Now $now -Version $version -Method 'PUT' -FilePath $filePath Write-Host "Status Code: $($response.StatusCode)" Write-Host $response.Content
Explanations:
- TBD
- No labels