带有 SAS token 的 Azure Blob 存储

标签 azure go

我正在尝试将文件作为 Blob 上传到 Azure 存储帐户,并且我有一个由此 “github.com/Azure/azure-storage-blob-go/azblob” 包提供的客户端。正如我在文档中看到的那样,应该可以使用 SAS Token 与存储进行通信,并使用

创建匿名凭证
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 代码,具体取决于请求 header 。

例如

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 header 不会改变任何内容。

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

总而言之,我的需要是将文件作为 blob 放入 Azure 存储帐户中,而第二个解决方案应该简单地工作,但不起作用,并且第一个解决方案未完成,因为我看不到传递的方法 SAS token 。我错过了什么?

最佳答案

因此,在第一种情况下,问题是 SAS token 在此包中没有传递。稍后在 url 创建过程中应将其添加到 URL,例如:

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

在第二种情况下,所有内容都与 Content-Length 相关,从 header 端无法更改。它在 http.NewRequest(...) 期间自动设置,但必须是以下类型之一:*bytes.Buffer*bytes.Reader*strings.Reader。否则为 0。但是 http.NewRequest(...) 接受 io.Reader 作为正文,因此它将使用实现 io.Reader 的所有内容进行编译> 接口(interface)类似于 *os.File,但它不会设置 Azure 存储帐户所需的 Content-Length。当我切换到上面列出的三种给定类型之一时,它开始工作。

关于带有 SAS token 的 Azure Blob 存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60228578/

相关文章:

node.js - 通过事件网格传递来自 Azure Function 的 HTTP 请求

windows - 如何在 Windows Azure 中安装和使用 COM 对象?

java - 如何修复从 REST 客户端使用 AZURE 表存储服务时指定的资源不存在错误

go - 在结构中取消引用指向 DB 的指针

go - 有递归打印树的内置方法吗?

go - 在 Docker for Go 程序中构建 Docker

asp.net - WCF 服务的内部终结点不适用于 Azure Web 角色

c# - Azure AD Graph api 返回禁止

go - 在 GO 中将多部分形式的数据读取为 []byte

database - GO 打开本地 postgres 连接