Connect to Azure Table Storage in R

I'm trying to connect to Azure Table Storage in R. Google search didn't return anything for people using R to connect to Rest APIs to store tables. The documentation is here . I tried to use an existing question about blob storage to connect (I couldn't even connect to blob using this), and refactored it for table storage queries, at the bottom:

library(httr)
url <- "https://rpoc.table.core.windows.net:443/dummytable(PartitionKey='0dfe725b-bd43-4d9d-b58a-90654d1d8741',RowKey='00b7595d-97c3-4f29-93de-c1146bcd3d33')?$select=<comma-separated-property-names>"
sak<-"u4RzASEJ3qbxSpf5VL1nY08MwRz4VKJXsyYKV2wSFlhf/1ZYV6eGkKD3UALSblXsloCs8k4lvCS6sDE9wfVIDg=="
requestdate<- http_date(Sys.time())
signaturestring<-paste0("GET",paste(rep("\n",12),collapse=""),
                        "x-ms-date:",requestdate,"
                        x-ms-version:2015-12-11")

headerstuff<-add_headers(Authorization=paste0("SharedKey rpoc:",
                                              RCurl::base64(digest::hmac(key=RCurl::base64Decode(sak, mode="raw"),
                                                                         object=enc2utf8(signaturestring),
                                                                         algo= "sha256", raw=TRUE))),
                         `x-ms-date`=requestdate,
                         `x-ms-version`= "2015-12-11",
                         `DataServiceVersion` = "3.0;NetFx",  
                         `MaxDataServiceVersion` = "3.0;NetFx" )
content(GET(url,config = headerstuff, verbose() ))

      

Console output:

-> GET /dummytable(PartitionKey='0dfe725b-bd43-4d9d-b58a-90654d1d8741',RowKey='00b7595d-97c3-4f29-93de-c1146bcd3d33')?$select=<comma-separated-property-names> HTTP/1.1
-> Host: rpoc.table.core.windows.net
-> User-Agent: libcurl/7.53.1 r-curl/2.6 httr/1.2.1
-> Accept-Encoding: gzip, deflate
-> Accept: application/json, text/xml, application/xml, */*
-> Authorization: SharedKey rpoc:nQWNoPc1l/kXydUw4rNq8MBIf/arJXkI3jZv+NttqMs=
-> x-ms-date: Mon, 24 Jul 2017 18:49:52 GMT
-> x-ms-version: 2015-12-11
-> DataServiceVersion: 3.0;NetFx
-> MaxDataServiceVersion: 3.0;NetFx
-> 
<- HTTP/1.1 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
<- Content-Length: 299
<- Content-Type: application/json
<- Server: Microsoft-HTTPAPI/2.0
<- x-ms-request-id: 2c74433e-0002-00b3-5aad-04d4db000000
<- Date: Mon, 24 Jul 2017 18:49:53 GMT
<- 
$odata.error
$odata.error$code
[1] "AuthenticationFailed"

$odata.error$message
$odata.error$message$lang
[1] "en-US"

$odata.error$message$value
[1] "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:2c74433e-0002-00b3-5aad-04d4db000000\nTime:2017-07-24T18:49:54.3878127Z"

      

The problem is with the authentication headers. Any help on how I could resolve this would be appreciated. I'm really surprised that more people don't use ATS with R as it is so versatile.

+3


source to share


2 answers


According to the REST link for Azure Storage Authentication based on your error information and code, the issue AuthenticationFailed

should be caused by an incorrect signature string for the Table Service without 12 redo characters \n

, which is different from it for Blob, Queue and File. Please read the link carefully Authentication for the Azure Storage Services

to find out the format of the differences for the table service as shown below.

Table Service (Shared Key Authentication)

StringToSign = VERB + "\n" +   
           Content-MD5 + "\n" +   
           Content-Type + "\n" +  
           Date + "\n" +  
           CanonicalizedResource;  

      

Table Service (Shared Key Authentication)

StringToSign = Date + "\n"   
           CanonicalizedResource  

      



Hope it helps.

0


source


I based my solution on PUT blob ( Azure PUT Blob Authentication Error in R ), then I adapted to use GET instead of PUT and table instead of blob.



library(httr)  

account <- "account"
container <- "container"  
key <- "u4RzASEJ..9wfVIDg=="  

url <- paste0("https://", account, ".table.core.windows.net/", container)
requestdate <- format(Sys.time(),"%a, %d %b %Y %H:%M:%S %Z", tz="GMT")
content_length <- 0

signature_string <- paste0("GET", "\n",            # HTTP Verb
                           "\n",                   # Content-MD5
                           "text/plain", "\n",     # Content-Type
                           requestdate, "\n",                   # Date
                           # Here comes the Canonicalized Resource
                           "/",account, "/",container)

headerstuff <- add_headers(Authorization=paste0("SharedKey ",account,":", 
                                                RCurl::base64(digest::hmac(key = 
                                                                             RCurl::base64Decode(key, mode = "raw"),
                                                                           object = enc2utf8(signature_string),
                                                                           algo = "sha256", raw = TRUE))),
                           `x-ms-date`= requestdate,
                           `x-ms-version`= "2015-02-21",
                           `Content-Type`="text/plain")

xml_body = content(GET(url, config = headerstuff, verbose()))

      

0


source







All Articles