为 Azure Blob 生成预签名 URL 引发空指针异常

Posted

技术标签:

【中文标题】为 Azure Blob 生成预签名 URL 引发空指针异常【英文标题】:Generate Presigned Url for Azure Blob throws Null pointer exception 【发布时间】:2021-09-26 22:48:40 【问题描述】:

我想生成一个预签名 URL /SAS,以便拥有该 URL 的任何人都可以访问我的文件。

SDK 版本:12.8.0

下面的代码是我写的:

BlockBlobClient blockBlobClient = objectStoreService.getBlobContainerClient().getBlobClient(fileName).getBlockBlobClient();

        String blobUrl = Utility.urlDecode(blockBlobClient.getBlobUrl());
        BlobSasPermission blobPermission = new BlobSasPermission()
                .setReadPermission(true);

        BlobServiceSasSignatureValues blobServiceSasSignatureValues = new BlobServiceSasSignatureValues(
                OffsetDateTime.now(ZoneOffset.UTC).plusSeconds(1000 * 60 * 60),
                blobPermission
        );
  
        blobUrl = blobUrl + "?" + blockBlobClient.generateSas(blobServiceSasSignatureValues);

但是代码抛出错误

java.lang.NullPointerException:参数不能为 null 或空字符串。参数名称:storageSharedKeyCredentials。

编辑 1:尝试使用:

UserDelegationKey userDelegationKey = blobServiceClient.getUserDelegationKey(keyStart,keyExpiry);

String blobUrl = Utility.urlDecode(blobClient.getBlobUrl());

blobUrl = blobUrl + "?" + blobClient.generateUserDelegationSas(blobServiceSasSignatureValues,userDelegationKey);

但现在得到:

"状态码 403, "AuthenticationFailedServer 未能验证请求。确保 Authorization 标头的值格式正确,包括签名。\nRequestId:7b0f0d75-d01e-00a8-4d84-7c9aa3000000\nTime:2021-07-19T09:54:31.1312999Z此资源级别不允许指定的签名资源"",

【问题讨论】:

错误非常简单 - 您需要创建 storageSharedKeyCredentials 来签署您的 SAS。 @GauravMantri ,我没有创建凭据的帐户密钥。在我的组织中,我们通过仅提供 sasToken、容器名称和容器 uri 的服务访问 blob 存储 要生成 SAS 令牌,您需要帐户密钥或使用 Azure AD 访问令牌。您不能使用另一个 SAS 令牌生成 SAS 令牌。 哦,好的。 @GauravMantri,有没有其他方法可以使用这些凭据(Sas 令牌、帐户名称、容器 URI、容器名称)为我的文件生成预签名的 url? 当然可以。我以为你想创建一个新的 SAS 令牌。是否要为给定所有这些参数的 blob 创建 SAS URL。对吗? 【参考方案1】:

假设您有一个具有有效权限、blob 容器 URL 和 blob 名称的 SAS 令牌,您可以使用以下简单逻辑为 blob 生成 SAS URL:

blob-container-url/blob-name?sas-token

如果您想使用 SDK,首先您将使用您的 blob 容器 URL 和 SAS 令牌创建一个 BlobContainerClient,然后使用该 blob 容器客户端创建一个 BlockBlobClient

BlobContainerClient blobContainerClient = new BlobContainerClientBuilder()
    .endpoint("blob-container-url?sas-token")
    .buildClient();

BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient("blob-name").getBlockBlobClient();

然后您可以使用此blockBlobClient 对您的 blob 执行操作。您可以使用getUrl() 方法获取blob 的URL。

【讨论】:

嗨,这段代码中生成的网址在哪里?我想与客户共享网址,以便他们可以直接访问/下载文件.. 可以使用getUrl()方法获取blob的URL。 这不是一个可共享的 URL 对吧?客户端将无法通过此 url 访问资源。 这将是一个可共享的 URL。请试一试。 已经尝试过...收到错误,因为不允许对该存储帐户进行公共访问

以上是关于为 Azure Blob 生成预签名 URL 引发空指针异常的主要内容,如果未能解决你的问题,请参考以下文章

为具有公共访问权限的文件上传生成预签名 URL

如何为 Azure Blob 存储中的文件夹生成共享访问签名?

尝试使用 SAS 访问 Azure blob 时收到“签名不匹配。使用的签名字符串是...”

S3 预签名上传 url 错误

使用 Cloudfront/CDN 预签名的 S3 URL

如何使用 amazon sdk 为虚域生成预签名的 Amazon S3 url?