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

Posted

技术标签:

【中文标题】Azure SAS 令牌不适用于 Azure.Storage.Blobs BlobServiceClient【英文标题】:Azure SAS Token not working with Azure.Storage.Blobs BlobServiceClient 【发布时间】:2020-04-10 19:59:57 【问题描述】:

我正在使用Azure.Storage.Blobs v12.1.0 库。我正在使用带有 Azure 服务主体凭据的用户委托生成 Blob 级 SAS 令牌,并尝试使用生成的 SAS 令牌上传 Blob。 我完全按照 Azure 中的 this code 示例生成 SAS 令牌。

这是我用来创建 SAS 令牌的代码:

string blobEndpoint = string.Format("https://0.blob.core.windows.net", storageProviderSettings.AccountName);

        TokenCredential credential =
            new ClientSecretCredential(
                storageProviderSettings.TenantId,
                storageProviderSettings.ClientId,
                storageProviderSettings.ClientSecret,
                new TokenCredentialOptions());

        BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(blobEndpoint),
                                                            credential);

        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
        BlobClient blobClient = containerClient.GetBlobClient(blobName);

        var delegationKey = await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddDays(7));
        BlobSasBuilder sasBuilder = new BlobSasBuilder()
        
            BlobContainerName = containerName,
            BlobName = blobName,
            Resource = "b",
            StartsOn = DateTimeOffset.UtcNow,
            ExpiresOn = DateTimeOffset.UtcNow.AddSeconds(expirySeconds)
        ;
        sasBuilder.SetPermissions(BlobSasPermissions.All);
        // if (withDownloadAccess) 
        //     sasBuilder.SetPermissions(BlobSasPermissions.Read);
        // 
        // if (withDeleteAccess) 
        //     sasBuilder.SetPermissions(BlobSasPermissions.Delete);
        // 
        Console.WriteLine(sasBuilder.Permissions);
        var sasQueryParams = sasBuilder.ToSasQueryParameters(delegationKey, storageProviderSettings.AccountName).ToString();
        UriBuilder sasUri = new UriBuilder()
        
            Scheme = "https",
            Host = string.Format("0.blob.core.windows.net", storageProviderSettings.AccountName),
            Path = string.Format("0/1", containerName, blobName),
            Query = sasQueryParams
        ;

        BlobServiceClient service = new BlobServiceClient(sasUri.Uri);

        await service.GetPropertiesAsync();

        Settings tmpUploadCredentials = CreateTemporaryAzureStorageProviderSettings(sasUri, storageProviderSettings);

        Console.WriteLine(tmpUploadCredentials.ConnectionString);
        return tmpUploadCredentials;

如果我将 SAS 令牌保存在浏览器中,则创建 SAS 令牌并且 Get Blob 工作正常,但如果我尝试上传文件或执行它现在正在工作的任何操作,则使用 BlobServiceClient。 为了检查它是否经过身份验证,我写了这行await service.GetPropertiesAsync();,它抛出了以下错误:

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

根据我的测试,service.GetPropertiesAsync(); 是帐户上的操作。这意味着它将调用Get Blob Service Propertiesrest api来获取帐户的blob服务的属性。但是,当您创建 BlobServiceClient 时,您需要提供 blob url。 blob 不支持该操作。所以你会得到错误。它将想要获取 blob 的属性,请致电api。所以,请将您的代码更新为以下代码


 BlobClient blobClient = new BlobClient(sasUri, null);
blobClient.GetPropertiesAsync();

更多详情请参考https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet#get-the-user-delegation-key

【讨论】:

非常感谢吉姆!!!犯了一个简单的错误,尝试使用没有意义的 Sas URI 创建 blobServiceClient,它应该是 BlobClient。但是在我粘贴的链接中,他们正在使用 URI 创建 BlobServiceClient。它误导了很多人,我为此在 azure-sdk-net 中提出了一个问题。再次非常感谢!

以上是关于Azure SAS 令牌不适用于 Azure.Storage.Blobs BlobServiceClient的主要内容,如果未能解决你的问题,请参考以下文章

具有 Azure AD 身份验证的 Azure 函数 - 允许的令牌受众不适用于 Microsoft Graph

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

Azure IoT 中心 SAS 令牌不会过期

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

使用 SAS 令牌从 Azure 阶段读取时出现雪花错误

如何在 Java 中基于 SAS 令牌访问 Azure WASB 容器?