How to get a Shared Access Signature on a Blob using the latest Azure SDK .NET API v12?
Sajeetharan's answer made me look for a BlobSasBuilder class, which actually exists.
Here is how I can build one on the server:
// 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);
Here is how to use it on the client side:
// 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);
Addendum
As mentioned by @one2012 in the comments, a page has been put up few months later after this answer showcasing all the features found in the Azure.Storage namespaces. The link can be useful to get more information.
After a fair amount of hunting, I have located some Microsoft documentation on this: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet
This details using a user delegation key to generate the SAS instead of the account key but the change is just a different overload to .ToSasQueryParameters() as described in other answers.
Some key snippets from the article to hook this up. First create your 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());
Get the user delegation key, this will be used to generate the 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));
Finally create the 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
};