使用 Blob 特定的 SAS 令牌连接和更新 Azure Blob

Posted

技术标签:

【中文标题】使用 Blob 特定的 SAS 令牌连接和更新 Azure Blob【英文标题】:Connect and update Azure Blob with Blob-specific SAS Token 【发布时间】:2021-09-12 10:54:27 【问题描述】:

我想要做什么:我有一个客户端(浏览器,而不是 node.js)JS 应用程序,它使用 @azure/storage-blob 包将文件上传到 Blob 存储。为此,它会从 Azure 函数中获取特定 Blob 的 SAS 令牌。 Blob 由函数在每个请求上创建,并向客户端返回一个 SAS 令牌。 Blob 和 SAS 生成工作,我可以在浏览器中打开带有 SAS 的 Blob Url 时下载它。

现在不起作用的是当我尝试将 BLOB SAS(不是存储帐户 SAS 或连接字符串)连接到存储帐户时。下面的代码在整个存储帐户中与 SAS 一起使用时有效,但我不想给予那么多权限。如果无法通过 Blob 服务客户端连接到特定 Blob,我不明白为什么可以为特定 Blob 创建 SAS 令牌。

可以为整个存储帐户创建只读 SAS 令牌,以启动和运行连接。但是 Blob SAS 之后会去哪里,以便可以访问 Blob?

我似乎错过了一些基本的东西,那么如何实现呢?

const url = `https://$storageName.blob.core.windows.net/$sasToken`; // sas for blob from the azure function
// const url = `https://$storageName.blob.core.windows.net$containerSas`; // sas from container
// const url = `https://$storageName.blob.core.windows.net/$containerName/$fileName$sasToken`; // does not work either
const blobService = new BlobServiceClient(url);

await this.setCors(blobService);

// get Container
const containerClient: ContainerClient = blobService.getContainerClient(containerName);

// get client
const blobClient = containerClient.getBlockBlobClient(fileName);

const exists = await blobClient.exists();
console.log('Exists', exists);

// set mimetype as determined from browser with file upload control
const options: BlockBlobParallelUploadOptions =  blobHTTPHeaders:  blobContentType: file.type  ;

// upload file
await blobClient.uploadBrowserData(file, options);

编辑:

Blob 的 SAS 令牌: ?sv=2018-03-28&sr=b&sig=somesecret&se=2021-07-04T15%3A14%3A28Z&sp=racwl

CORS 方法,虽然我可以确认它在我使用全局存储帐户 SAS 时有效:

private async setCors(blobService: BlobServiceClient): Promise<void> 
  var props = await blobService.getProperties();
  props.
    cors =
    [
      allowedOrigins: '*',
      allowedMethods: '*',
      allowedHeaders: '*',
      exposedHeaders: '*',
      maxAgeInSeconds: 3600
    ]
    ;

错误:

使用 Blob SAS 时,在 setCors/getProperties 方法处:403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)

使用以下服务 url 时,在 setCors/getProperties 方法中:https://$storageName.blob.core.windows.net/$containerName/$fileName$sasToken => RestError: The resource doesn't support specified Http Verb.

使用只有读取权限的存储帐户 SAS 时,访问 blob (blob.exists()) 时:403 (This request is not authorized to perform this operation using this resource type.)(有道理,但我想使用 Blob 特定的 SAS)

【问题讨论】:

几个问题:1) 你能分享一下你的 SAS 令牌是什么样子的吗?您可以混淆令牌的sig 部分。 2)当你说“它不工作”时,你能详细说明一下吗?代码的哪一部分失败了? 3) 请包含setCors 方法的代码。请编辑您的问题并提供该信息。 【参考方案1】:

您遇到此错误的原因是您尝试使用为 blob 创建的 SAS 令牌(即Service SAS)设置 CORS。 CORS 操作是服务级别操作,为此您需要使用在帐户级别获得的 SAS 令牌。换句话说,您将需要使用Account SAS。为 blob 容器或 blob 创建的任何 SAS 令牌都是 Service SAS 令牌。

话虽如此,您确实不需要在每个请求中为存储帐户设置 CORS 属性。这是您在创建帐户时可以执行的操作。

一旦您从代码中删除对 setCors 方法的调用,它应该可以正常工作。

考虑到您只使用 Blob SAS,您可以通过直接使用 SAS URL 创建BlockBlobClient 的实例来大大简化您的代码。例如,您的代码可以很简单:

const url = `https://$storageName.blob.core.windows.net/$containerName/$fileName$sasToken`;
const blobClient = new BlockBlobClient(url);
//...do operations on blob using this blob client

【讨论】:

效果很好,谢谢。从所有示例和文档中都不清楚我可以跳过 CORS 并直接调用 BlobClient

以上是关于使用 Blob 特定的 SAS 令牌连接和更新 Azure Blob的主要内容,如果未能解决你的问题,请参考以下文章

Azure CDN URL使用令牌身份验证和Blob存储SAS重写规则

有没有办法重新生成 Azure Blob 存储 SAS 令牌

如何使用 SAS 令牌从 C# 连接到 Azure BlobStorage?

通过带有 SAS 令牌的 Power Shell 列出 Azure Blob 容器中文件夹中的文件

Azure SAS 令牌不适用于 Azure.Storage.Blobs BlobServiceClient

Azure 存储帐户生成 SAS 令牌,而不是 SAS URI