簡體   English   中英

如何使用最新的 Azure SDK .NET API v12 在 Blob 上獲取共享訪問簽名?

[英]How to get a Shared Access Signature on a Blob using the latest Azure SDK .NET API v12?

我曾經能夠使用 v11 Azure SDK API 在 Blob 上創建共享訪問簽名,如下所示:

var containerName = "mycontainer";
var blobName = "myblob";

CloudStorageAccount storageAccount 
 = CloudStorageAccount.Parse(<StorageConnectionString>);

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

CloudBlobContainer container = blobClient.GetContainerReference(containerName);


SharedAccessBlobPermissions permission = SharedAccessBlobPermissions.Read;

TimeSpan clockSkew = TimeSpan.FromMinutes(15d);
TimeSpan accessDuration = TimeSpan.FromMinutes(15d);

var blobSAS = new SharedAccessBlobPolicy
{
    SharedAccessStartTime = DateTime.UtcNow.Subtract(clockSkew),
    SharedAccessExpiryTime = DateTime.UtcNow.Add(accessDuration) + clockSkew,
    Permissions = permissions
};

CloudBlockBlob blob = container.GetBlockBlobReference(blobName);

string sasBlobToken = blob.GetSharedAccessSignature(blobSAS);

...

我想使用最新的 v12 .NET API,它似乎用CloudBlobClient替換了BlobServiceClient ,用CloudBlobContainer替換了 CloudBlobContainer,用BlobContainerClient CloudBlockBlobBlobClient

但是,在BlobClient實例上可用的方法GetSharedAccessSignatureCloudBlockBlob實例上不可用。

問題

如何使用最新的 Azure SDK .NET API v12 從BlobClient實例獲取共享訪問簽名?

Sajeetharan 的回答讓我尋找一個實際存在的BlobSasBuilder類。

這是我如何在服務器上構建一個:

//  Creates a client to the BlobService using the connection string.
var blobServiceClient = new BlobServiceClient(storageConnectionString);

//  Gets a reference to the container.
var blobContainerClient = blobServiceClient.GetBlobContainerClient(<ContainerName>);

//  Gets a reference to the blob in the container
BlobClient blobClient = containerClient.GetBlobClient(<BlobName>);

//  Defines the resource being accessed and for how long the access is allowed.
var blobSasBuilder = new BlobSasBuilder
{
    StartsOn = DateTime.UtcNow.Subtract(clockSkew), 
    ExpiresOn = DateTime.UtcNow.Add(accessDuration) + clockSkew,
    BlobContainerName = <ContainerName>,
    BlobName = <BlobName>,
};
    
//  Defines the type of permission.
blobSasBuilder.SetPermissions(BlobSasPermissions.Write);
       
//  Builds an instance of StorageSharedKeyCredential      
var storageSharedKeyCredential = new StorageSharedKeyCredential(<AccountName>, <AccountKey>);

//  Builds the Sas URI.
BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential);

以下是在客戶端使用它的方法:

//  Builds the URI to the blob storage.
UriBuilder fullUri = new UriBuilder()
{
    Scheme = "https",
    Host = string.Format("{0}.blob.core.windows.net", <AccountName>),
    Path = string.Format("{0}/{1}", <ContainerName>, <BlobName>),
    Query = sasQueryParameters.ToString()
};

//  Get an instance of BlobClient using the URI.
var blobClient = new BlobClient(fullUri.Uri, null);

//  Upload stuff in the blob.
await blobClient.UploadAsync(stream);

附錄

正如@one2012 在評論中所提到的,在這個答案展示了 Azure.Storage 命名空間中的所有功能幾個月后一個頁面已經建立 該鏈接可用於獲取更多信息。

經過大量的搜索,我找到了一些關於此的 Microsoft 文檔: https : //docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet

這詳細說明了使用用戶委托密鑰來生成 SAS 而不是帳戶密鑰,但更改只是 .ToSasQueryParameters() 的不同重載,如其他答案中所述。

文章中的一些關鍵片段將其聯系起來。 首先創建您的 BlobServiceClient:

// Construct the blob endpoint from the account name.
string blobEndpoint = string.Format("https://{0}.blob.core.windows.net", accountName);

// Create a new Blob service client with Azure AD credentials.
BlobServiceClient blobClient = new BlobServiceClient(new Uri(blobEndpoint),
                                                     new DefaultAzureCredential());

獲取用戶委托密鑰,這將用於生成 SAS:

// Get a user delegation key for the Blob service that's valid for seven days.
// You can use the key to generate any number of shared access signatures over the lifetime of the key.
UserDelegationKey key = await blobClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                   DateTimeOffset.UtcNow.AddDays(7));

最后創建 SAS URI:

// Create a SAS token that's valid for one hour.
BlobSasBuilder sasBuilder = new BlobSasBuilder()
{
    BlobContainerName = containerName,
    BlobName = blobName,
    Resource = "b",
    StartsOn = DateTimeOffset.UtcNow,
    ExpiresOn = DateTimeOffset.UtcNow.AddHours(1)
};

// Specify read permissions for the SAS.
sasBuilder.SetPermissions(BlobSasPermissions.Read);

// Use the key to get the SAS token.
string sasToken = sasBuilder.ToSasQueryParameters(key, accountName).ToString();

// Construct the full URI, including the SAS token.
UriBuilder fullUri = new UriBuilder()
{
    Scheme = "https",
    Host = string.Format("{0}.blob.core.windows.net", accountName),
    Path = string.Format("{0}/{1}", containerName, blobName),
    Query = sasToken
};

使用適用於 .NET 的 Azure Blob 存儲客戶端庫 v12:

BlobSasBuilder blobSasBuilder = new BlobSasBuilder()
{
    BlobContainerName = blobContainerName,
    BlobName = blobName,
    Resource = "b", //b = blob, c = container
    StartsOn = DateTimeOffset.UtcNow,
    ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(lifetimeMinutes)
};

blobSasBuilder.SetPermissions(BlobSasPermissions.Read);

StorageSharedKeyCredential storageSharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);

string sas = blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();

如果必須根據分配給容器的訪問策略生成共享訪問簽名(SAS 令牌),請使用以下方法

BlobSasBuilder blobSasBuilder = new BlobSasBuilder()
{
    BlobContainerName = blobContainerName,
    BlobName = blobName,
    Resource = "b", //b = blob, c = container
    Identifier = "ReadOnlyPolicy" //string value referees to the access policy created and assigned to the container.
};

StorageSharedKeyCredential storageSharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);

string sas = blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();

注意:當 SAS 令牌生成基於分配給容器的訪問策略時,您將無法在 BlobSasBuilder 中定義權限、開始或結束時間。 您將收到運行時異常,因為“訪問策略字段可以與簽名或 SAS 標識符相關聯,但不能同時與兩者相關聯”

參考: https : //www.craftedforeveryone.com/beginners-guide-and-reference-to-azure-blob-storage-sdk-v12-dot-net-csharp/

https://www.craftedforeveryone.com/beginners-guide-and-reference-to-azure-blob-storage-sdk-v12-dot-net-csharp/#generate_access_policy_based_sas_token_for_a_blob

在這里: https : //docs.microsoft.com/en-us/rest/api/storageservices/delegate-access-with-shared-access-signature聲明 Azure 存儲支持三種不同類型的共享訪問簽名 (SAS) :

  1. 帳戶級別 SAS,這是您在 v11 SDK 中使用的。 此處的詳細信息和示例: https : //docs.microsoft.com/en-us/azure/storage/common/storage-account-sas-create-dotnet
  2. 服務級別 SAS,使用 v12(和 V11)SDK。 此處的詳細信息和示例: https : //docs.microsoft.com/en-us/azure/storage/blobs/sas-service-create?tabs=dotnet
  3. 用戶委派 SAS,這是 Microsoft 推薦的方法,提供您可以使用 Azure Active Directory 用戶使用 v12 SDK 進行簽名。 此處的詳細信息和示例: https : //docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet

1 和 2 都使用帳戶的共享密鑰來生成 SAS 令牌,而 3 使用從 AAD 帳戶用戶生成的密鑰,因此更安全,更容易在需要時(理論上)被撤銷。 請參閱https://docs.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas#:~:text=Authorization%20of%20a%20user%20delegation%20SAS,-When%20a %20client&text=這個%20approach%20provides%20an%20additional,是%20a%20security%20best%20practice 有關為什么這更安全的更多詳細信息(“這種方法提供了額外的安全級別,並避免了將帳戶訪問密鑰與應用程序代碼一起存儲的需要。出於這些原因,使用 Azure AD 憑據創建 SAS 是一種安全最佳實踐.”)

現在所有都由存儲帳戶支持使用,但我的印象是帳戶級別不支持在 v12 SDK 中實現(我在猜測 - 所以不要引用我,但我也找不到這個),或者有一些其他的隱藏方式做到這一點(當然是BlobSasBuilder.ToSasQueryParameters()方法只有兩個重載),我猜葉子用戶委托或服務水平,你現在是為了執行辦法。

你可以做

SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy
{
    // Expiration is in 12 hours.
    SharedAccessExpiryTime = DateTime.UtcNow.AddHours(12),
    Permissions = permissions
};

並傳遞值

 // Generate the shared access signature on the container, setting the constraints directly on the signature
 CloudBlobContainer container = blobClient.GetContainerReference(containerName);
 string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);

使用V12,您可以

 StorageSharedKeyCredential Credential = new StorageSharedKeyCredential(accountName, accountKey);
  // Use the key to get the SAS token.
 string sasToken = accountSasBuilder.ToSasQueryParameters(Credential).ToString();

SAMPLE CODE

使用適用於 .NET 的 Azure Blob 存儲客戶端庫 v12:

        BlobSasBuilder blobSasBuilder = new BlobSasBuilder()
        {
            BlobContainerName = blobContainerName,
            BlobName = blobName,
            Resource = "b", //b = blob, c = container
            StartsOn = DateTimeOffset.UtcNow,
            ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(lifetimeMinutes)
        };

        blobSasBuilder.SetPermissions(BlobSasPermissions.Read);

        StorageSharedKeyCredential storageSharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);

        string sas = blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
private string BuildSASUri(BlobClient blob)
{
    // Create a user SAS that only allows reading for a minute
    BlobSasBuilder sas = new BlobSasBuilder 
    {
        BlobContainerName = blob.BlobContainerName,
        BlobName = blob.Name,
        Resource = "b",
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(1)
    };
    // Allow read access
    sas.SetPermissions(BlobSasPermissions.Read);
    var storageSharedKeyCredential = new StorageSharedKeyCredential(
        _iconfiguration.GetValue<string>("StorageAccount:AccountName"),
        _iconfiguration.GetValue<string>("StorageAccount:AccountKey")
    );

    return sas.ToSasQueryParameters(storageSharedKeyCredential).ToString();
}

以上是我的工作代碼。

但是,我不知道如何使用 V12 創建存儲訪問策略。 應該是這樣的: https : //docs.microsoft.com/en-us/dotnet/api/azure.storage.blobs.blobcontainerclient.setaccesspolicy?view=azure-dotnet

但我認為微軟完全忘記了提供一種創建 BlobSignedIdentifier 的方法。

文檔已過期: https : //docs.microsoft.com/en-us/azure/storage/common/storage-stored-access-policy-define-dotnet?toc=% 2fazure%2fstorage%2fblobs% 2ftoc。 json

它使用 Microsoft.Azure.Storage.Blob,但https://www.nuget.org/packages/Microsoft.Azure.Storage.Blob/說不要再使用它了。

就我而言,解決方案似乎非常簡單和優雅:

我的舊代碼:

    using Microsoft.Azure.Storage.Blob;
    private readonly CloudBlobContainer _container;
    private Uri GetSharedAccessUri(string filename)
    {
        var blob = _container.GetBlockBlobReference(filename);
        var sas = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy
        {
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddYears(1)
        });
        return new Uri(blob.Uri, sas);
    }

我的新代碼:

    using Azure.Storage.Blobs;
    private readonly BlobContainerClient _container;
    private Uri GetSharedAccessUri(string filename)
    {
        var blob = _container.GetBlockBlobClient(filename);
        var sas = blob.GenerateSasUri((BlobSasPermissions)BlobContainerSasPermissions.Read, DateTime.UtcNow.AddYears(1));

        return new Uri(blob.Uri, sas);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM