具有SAS令牌的Azure Blob存储

时间:2020-02-14 14:48:59

标签: azure go

我正尝试以Blob的身份将文件上传到Azure存储帐户,并且我有此"github.com/Azure/azure-storage-blob-go/azblob"程序包提供的客户端。正如我在文档中看到的那样,应该可以使用SAS Token

创建匿名凭证来与Storage通信
credential := azblob.NewAnonymousCredential()
po := azblob.PipelineOptions{
    Log: pipeline.LogOptions{
        Log: func(s pipeline.LogLevel, m string) {
            log.Tracef("pipeline message: %s", m)
        },
        ShouldLog: func(level pipeline.LogLevel) bool {
            return level <= pipeline.LogError
        },
    },
}
pipeline := azblob.NewPipeline(credential, po)

但是,在请求访问权限之后,我看不到通过其他服务收到的SAS Token的选项。

我还尝试使用Azure存储帐户REST API“手动”执行此操作,因此我的URL类似于https://servicename.blob.core.windows.net/containerID/BlobID?sasToken...,但根据请求标头,我得到的只是400、411和501 HTTP代码。

例如

req.Header.Add("Accept", "*/*")
req.Header.Add("Accept-Language", "en-US,en;q=0.5 --compressed")
req.Header.Add("Accept-Encoding", "gzip, deflate, br")
req.Header.Add("content-type", "application/octet-stream")
req.Header.Add("x-ms-version", "2019-02-02")
req.Header.Add("x-ms-blob-type", "BlockBlob")
req.Header.Add("x-ms-client-request-id", "someID")
req.Header.Add("Connection", "keep-alive")
req.Header.Add("Content-Length", "512000")
req.Header.Add("Transfer-Encoding", "gzip, chunked, deflate")

我收到400个密码,

<?xml version="1.0" encoding="utf-8"?>
<Error>
    <Code>MissingRequiredHeader</Code>
        <Message>
            An HTTP header that's mandatory for this request is not specified.
            RequestId:someId
            Time:2020-02-14T13:47:58.8383371Z
        </Message>
    <HeaderName>x-ms-original-content-length</HeaderName>
</Error> 

添加x-ms-original-content-length标头不会改变任何内容。

有趣的事实是,只有当我在Go代码中尝试时,它才会发生。当我尝试任何REST客户端时,它都在使用这些标头。

总而言之,我需要将文件作为Blob放入Azure存储帐户,第二个解决方案应该简单地起作用,不起作用,并且第一个解决方案没有完成,因为我看不到传递方法{ 1}}。我想念什么?

1 个答案:

答案 0 :(得分:2)

因此,在第一种情况下,问题在于SAS令牌在此软件包中未传递。应该稍后在创建URL时将其添加到URL,例如:

URL, err := url.Parse(blobURL + "/" + containerName + "/" + blobName + "?token as query"

在第二种情况下,所有内容都与Content-Length有关,而这在页眉侧是不可更改的。它是在http.NewRequest(...)期间自动设置的,但是它必须是以下类型之一:*bytes.Buffer*bytes.Reader*strings.Reader。否则为0。但是http.NewRequest(...)接受io.Reader作为主体,因此它将与实现io.Reader的接口(如*os.File)一起编译,但是不会设置Content-Length对于Azure存储帐户是必需的。当我切换到三种给定类型之一时,上面列出的它开始工作。