我一直在尝试连接到R中的Azure表存储.Google搜索没有返回任何关于使用R连接到Rest API进行表存储的人的信息。文档在这里。我尝试将有关 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-04d4db000000nTime:2017-07-24T18:49:54.3878127Z"
问题似乎是身份验证标头。关于我如何解决这个问题的任何帮助将不胜感激。我真的很惊讶更多的人不使用 ATS 和 R,因为它是如此通用。
我的解决方案基于 PUT blob 问题(Azure PUT Blob 身份验证在 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()))
根据 Azure 存储身份验证的 REST 参考,根据错误信息和代码,问题AuthenticationFailed
应由表服务的签名字符串不正确引起,没有 12 个重复符号n
,这与 Blob、队列和文件服务的签名字符串不同。请仔细查看参考Authentication for the Azure Storage Services
以了解表服务的差异格式,如下所示。
表服务(共享密钥身份验证(
StringToSign = VERB + "n" + Content-MD5 + "n" + Content-Type + "n" + Date + "n" + CanonicalizedResource;
表服务(共享密钥精简版身份验证(
StringToSign = Date + "n" CanonicalizedResource
希望对您有所帮助。
派对有点晚了,但是:现在有一个AzureTableStor包,它也在CRAN上。
library(AzureTableStor)
# storage account endpoint
endp <- table_endpoint("https://mystorageacct.table.core.windows.net", key="mykey")
# Cosmos DB w/table API endpoint
endp <- table_endpoint("https://mycosmosdb.table.cosmos.azure.com:443", key="mykey")
list_storage_tables(endp)
tab <- storage_table(endp, "mytable")
insert_table_entity(tab, list(
RowKey="row1",
PartitionKey="partition1",
firstname="Bill",
lastname="Gates"
))
get_table_entity(tab, "row1", "partition1")
免责声明:我是这个软件包的开发者。