2017-07-24 39 views
3

我一直在嘗試連接到R中的Azure表存儲。Google搜索對使用R連接到Rest API以進行表存儲的人沒有返回任何內容。該文檔是here。我嘗試了一個關於blob存儲的現有question來連接(我無法使用它連接到一個blob),並重新使用它來進行表存儲查詢。下圖:連接到R中的Azure表存儲

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())) 

控制檯輸出:

-> 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" 

問題看起來是認證頭。任何幫助我如何解決這個問題將不勝感激。我真的感到驚訝,因爲它的多功能性讓更多的人不使用ATS。

回答

0

根據對Azure存儲的身份驗證REST參考,根據你的錯誤信息&代碼,這個問題AuthenticationFailed應該由不正確的簽名字符串表服務無12個重複的符號\n,這是不同的,對於造成的Blob,隊列和文件服務。請仔細參閱Authentication for the Azure Storage Services以瞭解Table服務的差異格式,如下所示。

表服務(共享密鑰認證)

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

表服務(共享密鑰認證精簡版)

StringToSign = Date + "\n" 
      CanonicalizedResource 

希望它能幫助。

0

我基於我的解決方案在PUT blob問題(Azure PUT Blob authentication fails in R),然後我適應使用GET而不是PUT和表而不是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()))