【问题标题】:Connecting to Azure Table Storage in R在 R 中连接到 Azure 表存储
【发布时间】:2017-12-30 12:05:23
【问题描述】:

我一直在尝试连接到 R 中的 Azure 表存储。Google 搜索没有返回任何关于使用 R 连接到用于表存储的 Rest API 的人的信息。文档是here。我尝试使用现有的question 关于 blob 存储进行连接(我什至无法使用它连接到 blob)并重新处理表存储查询。下面:

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 与 R 一起使用,因为它用途广泛。

【问题讨论】:

    标签: r rest azure azure-blob-storage azure-table-storage


    【解决方案1】:

    根据Azure Storage Authentication的REST reference,根据您的错误信息和代码,问题AuthenticationFailed应该是由没有12个重复符号\n的表服务的签名字符串不正确引起的,这是不同的来自 Blob、队列和文件服务。请仔细参考Authentication for the Azure Storage Services了解Table服务的不同格式,如下所示。

    表服务(共享密钥认证)

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

    表服务(Shared Key Lite 身份验证)

    StringToSign = Date + "\n"   
               CanonicalizedResource  
    

    希望对你有帮助。

    【讨论】:

      【解决方案2】:

      我的解决方案基于 PUT blob 问题 (Azure PUT Blob authentication fails in R),然后我适应使用 GET 而不是 PUT 和 table 而不是 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()))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-18
        • 1970-01-01
        • 2022-08-03
        • 2015-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多