0
votes

I'm trying to make a request against the azure storage API, to an account which is not publicly visible, and needs requests to be authenticated.

I was trying to follow this page for the headers: https://msdn.microsoft.com/en-us/library/azure/dd179428.aspx

I simply can't make this work. I always get a "ResourceNotFound" error, which I can't explain as I'm definitely not mistyping the storage account or the container names. I've also connected to Power BI successfully using the same account, container and key.

The only thing I can think off might be with the generation of the Signature, I could be lost in the encodings (first time I'm doing some such thing).. However that doesn't explain the error message being "ResourceNotFound". Here's the code to the request (R):

#azure storage endpoint to hit against
account <- "myaccount"
container <- "mycontainer"
requestProperties <- "comp=list"
endPoint <- paste("https://", account, ".blob.core.windows.net/", sep = "")
endPoint
#[1] "https://myaccount.blob.core.windows.net/"


#date header
timeStamp <- Sys.time()
timeString <- format(timeStamp, format="%y-%m-%d %H:%M:%S", tz="GMT", usetz = TRUE)
timeString <- "Fri, 30 Sep 2016 14:54:30 GMT"
dateHeader <- paste("x-ms-date", timeString, sep = ":")
dateHeader
#[1] "x-ms-date:Fri, 30 Sep 2016 14:54:30 GMT"

#version header
versionHeader <- "x-ms-version:2015-02-21"

#authorization header
requestVerb <- "GET"
authType <- "SharedKey"
azureKey <- "myAccountKey"

newLines <- "\n\n\n\n\n\n\n\n\n\n"
canonicalizedHeaders <- paste(dateHeader,versionHeader, sep = "\n")

#build canonicalized resource
resourceAccount <- paste("/",account, sep = "")
resourceContainer <- paste ("/",container, sep = "")
resource <- paste(resourceAccount, resourceContainer, sep = " ")

canonicalizedResource <- paste(resource, requestProperties, sep = "\n")
canonicalizedResource
#[1] "/myaccount /mycontainer\ncomp=list"

#build authentication signed string
stringToSign <- paste(requestVerb, newLines, canonicalizedHeaders, canonicalizedResource, sep = "\n")
stringToSign <- enc2utf8(stringToSign)
stringToSign
#[1] "GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 30 Sep 2016 14:54:30 GMT\nx-ms-version:2015-02-21\n/myaccount /mycontainer\ncomp=list"

Signature  <- digest::hmac(object = stringToSign, key = azureKey, algo = "sha256", serialize = FALSE)

#authentication header
authorization <- paste(account, Signature, sep = ":")
authorization
#[1] "myaccount:b4761595ea09d0e9d56223bd0a14233bca2b9fc3bb043031586215942f5c6d06"

authHeader <- paste("Authorization:", authType, authorization, sep = " ")
authHeader
#[1] "Authorization: SharedKey myaccount:b4761595ea09d0e9d56223bd0a14233bca2b9fc3bb043031586215942f5c6d06"


#build the actual request
request <- paste(endPoint, requestProperties, sep = "?")
request
#[1] "https://myaccount.blob.core.windows.net/?comp=list"

azureRequest <- httr::GET(request, httr::add_headers(dateHeader, versionHeader, authHeader))
responseContent <- httr::content(azureRequest, as = "text")
responseContent
#[1] "<?xml version=\"1.0\" encoding=\"utf-8\"?><Error><Code>ResourceNotFound</Code><Message>The specified resource does not exist.\nRequestId:b1e87500-0001-0003-6231-1b7598000000\nTime:2016-09-30T15:44:52.3452448Z</Message></Error>"

Am I missing something while generating the request? Do I need to do something with my account to allow access through the REST API?

2
So doesn't MS provide a dummy account with publicly available authentication keys for demonstration purposes? Otherwise you should just go to some Azure-specific forum because the-rest-of-us-non-Azure-useRs won't be able to test any answers.IRTFM
I hope that is not your real SharedKeypaparazzo
Try putting the container in the path. e.g. http://<storage-account>.blob.core.windows.net/mycontainerpaparazzo

2 Answers

1
votes

Try accessing blob using http://storageexplorer.com/ tool and see if you can access the blob.

Here is a thread that gives a sample code how to construct Authorization header for the REST API using SAS/Account names.
Azure - call Storage rest api for list blobs

0
votes

Is there a reason why you aren't using the Storage SDK's which perform this logic for you. We have them in all major languages - see the list of tabs at the top of this Getting Started guide. Alternatively, we have all the source code for these libraries available on GitHub (eg - here is the .NET source code) and you can see the signing logic inside the source code - check out SharedAccessSignatureHelper for SAS tokens (here).