连接到R中的Azure表存储

问题描述:

我一直在尝试连接到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。

根据对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 

希望它能帮助。

我基于我的解决方案在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()))