Azure PUT Blob authentication fails in R

老子叫甜甜 提交于 2019-12-31 04:05:09

问题


I would like to use R and the Azure Storage's Put Blob API to put files into my blob storage account but it fails to authenticate my request. Unfortunately, I couldn't find any documentation or sample code for R. General documentation of Put Blob API: https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob

Here is the code that I tried to use:

library(httr)  

account <- "myAccount"  
container <- "myContainer"  
filename <- "test.txt"  
key <- "primaryKey"  
object <- "Hello World" 

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

signature_string <- paste0("PUT", "\n", "\n", "\n",
                       content_length, "\n", 
                       "\n",
                       "x-ms-date:",requestdate, "\n", 
                       "x-ms-version:2015-02-21", "\n",
                       "x-ms-blob-type:BlockBlob", "\n",
                       "Content-Type:text/plain",  "\n",
                       "\n",
                       "x-ms-blob-content-dis filename=", filename, "\n",
                       "\n",
                       "/",account, "/",container,"/", filename)

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))),
                       `Content-Length` = content_length,
                       `x-ms-date`= requestdate,
                       `x-ms-version`= "2015-02-21",
                       `x-ms-blob-type`="BlockBlob",
                       `Content-Type`="text/plain")

content(PUT(url, config = headerstuff, body = object, verbose()), as = "text")`

Request it sends:

-> PUT /myContainer/test.txt HTTP/1.1
-> Host: myAccount.blob.core.windows.net
-> User-Agent: libcurl/7.49.1 r-curl/2.3 httr/1.2.1
-> Accept-Encoding: gzip, deflate
-> Accept: application/json, text/xml, application/xml, */*
-> Authorization: SharedKey myAccount:hashedSignatureString
-> Content-Length: 11
-> x-ms-date: Tue, 13 Jun 2017 08:50:38 GMT
-> x-ms-version: 2015-02-21
-> x-ms-blob-type: BlockBlob
-> Content-Type: text/plain
-> 
>> Hello World

Response:

<- 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: 693
<- Content-Type: application/xml
<- Server: Microsoft-HTTPAPI/2.0
<- x-ms-request-id: efc2c8de-0001-00a9-3d21-e41b06000000
<- Date: Tue, 13 Jun 2017 08:48:56 GMT

I tried the same with the List Blobs API (with some minor changes in the formatting of the headers) and it works well, but I can't make it work with Put Blob. List Blob solution from here: https://stackoverflow.com/a/29286040/8085694

Could you please provide some sample R code for Authentication header creation at Put Blob or help me resolve this issue?

Also, if I go further, is it possible somehow to upload R objects as blobs to the storage?

Thanks in advance,

Gábor


回答1:


I managed to resolve this issue by putting the "\n" characters and everything in the right place. Based on Gaurav Mantri's help, I used:
https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services

The following changes in the 'signature_string' worked:

signature_string <- paste0("PUT", "\n",            # HTTP Verb
                           "\n",                   # Content-Encoding  
                           "\n",                   # Content-Language
                           content_length, "\n",   # Content-Length
                           "\n",                   # Content-MD5
                           "text/plain", "\n",     # Content-Type
                           "\n",                   # Date
                           "\n",                   # If-Modified-Since
                           "\n",                   # If-Match  
                           "\n",                   # If-None-Match
                           "\n",                   # If-Unmodified-Since
                           "\n",                   # Range
                           # Here comes the Canonicalized Headers
                           "x-ms-blob-type:BlockBlob","\n",
                           "x-ms-date:",requestdate,"\n",
                           "x-ms-version:2015-02-21","\n",
                           # Here comes the Canonicalized Resource
                           "/",account, "/",container,"/", filename)



回答2:


There is an Azure offical R package Microsoft/AzureSMR on GitHub, which can help you easier using R & Azure Blob Storage, you can refer to its tutorial to know more details.

If you just want to use some Azure services like Blob Storage, not else, I think some source codes of this project are very valuable for rebuilding your code better, such as createAzureStorageSignature method which can directly help building the signature to resolve your issue.



来源:https://stackoverflow.com/questions/44519413/azure-put-blob-authentication-fails-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!