Reputation: 894
Having some trouble with this one. I'm getting an SAS token generated after following the examples in Microsoft's documentation, but am having issues with the SAS token not being authenticated.
string sastoken = "";
BlobServiceClient blobServiceClient = new BlobServiceClient("DefaultEndpointsProtocol=https;AccountName=accountname;AccountKey=accountkey;EndpointSuffix=core.windows.net");
string containerName = containername;
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
BlobSasBuilder sasBuilder = new BlobSasBuilder()
{
ExpiresOn = DateTime.UtcNow + (new TimeSpan(24, 0, 0)),
BlobContainerName = containerName,
BlobName = imageData.filename,
Resource = "b"
};
sasBuilder.SetPermissions(BlobSasPermissions.Read);
sastoken = sasBuilder.ToSasQueryParameters(new StorageSharedKeyCredential(containername, credentialkey)).ToString();
UriBuilder fulluri = new UriBuilder()
{
Scheme = "https",
Host = string.Format("{0}.blob.core.windows.net", containername),
Path = string.Format("{0}/{1}", "blobtest", "file.bmp"),
Query = sastoken
};
imageData.url = fulluri.Uri.ToString();
imageData.url returns as: https://accountname.blob.core.windows.net/containername/file.bmp?sv=2019-07-07&se=2020-07-10T14%3A54%3A43Z&sr=b&sp=r&sig=UXvC7SAXqQtsVgfXj6L%2BOIinTMhQj%2F3NH95v%2FLRvM8g%3D
I get an authentication error, but the entire point of SAS tokens is to provide that authentication. I'm sure that I'm missing something here, but haven't found anywhere that I'm making a mistake. Most of the information I find is related to the Microsoft.Azure.Storage package rather than the Azure.Storage.Blob namespace. Any help or advice would be welcome. Thanks!
Upvotes: 5
Views: 6970
Reputation: 1075
Since a year or 2 there is official migration guidance docs available. These also expose the existence of a convenience method for generating a sas token url.
// Create a BlobClient with a shared key credential
BlobClient blobClient = new BlobClient(blobUri, sharedKeyCredential);
Uri sasUri;
// Ensure our client has the credentials required to generate a SAS
if (blobClient.CanGenerateSasUri)
{
// Create full, self-authenticating URI to the resource from the BlobClient
sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Read, DateTimeOffset.UtcNow.AddHours(1));
// Use newly made as SAS URI to download the blob
await new BlobClient(sasUri).DownloadToAsync(new MemoryStream());
}
This example and more can be found here:
Upvotes: 0
Reputation: 14034
I use something like this, using the Microsoft.WindowsAzure.Storage
nuget package:
private Uri GetSasForBlob(CloudBlob blob, DateTime expiry, SharedAccessBlobPermissions permissions = SharedAccessBlobPermissions.None)
{
var offset = TimeSpan.FromMinutes(10);
var policy = new SharedAccessBlobPolicy
{
SharedAccessStartTime = DateTime.UtcNow.Subtract(offset),
SharedAccessExpiryTime = expiry.Add(offset),
Permissions = permissions
};
#pragma warning disable CA5377 // Use Container Level Access Policy
var sas = blob.GetSharedAccessSignature(policy);
#pragma warning restore CA5377 // Use Container Level Access Policy
return new Uri($"{blob.Uri}{sas}");
}
UPDATE using Azure.Storage.Blobs
:
// Read these from config:
// var accountName = "accountname";
// var accountKey = "xxxxxxx";
// var blobServiceEndpoint = $"https://{accountName}.blob.core.windows.net";
private Uri GetSasForBlob(string blobname, string containerName, DateTime expiry, BlobAccountSasPermissions permissions = BlobAccountSasPermissions.Read)
{
var offset = TimeSpan.FromMinutes(10);
var credential = new StorageSharedKeyCredential(accountName, accountKey);
var sas = new BlobSasBuilder
{
BlobName = blobname,
BlobContainerName = containerName,
StartsOn = DateTime.UtcNow.Subtract(offset),
ExpiresOn = expiry.Add(offset)
};
sas.SetPermissions(permissions);
UriBuilder sasUri = new UriBuilder($"{blobServiceEndpoint}/{containerName}/{blobname}");
sasUri.Query = sas.ToSasQueryParameters(credential).ToString();
return sasUri.Uri;
}
Upvotes: 4
Reputation: 2887
It looks like your generated SAS token and URL are using different values for account name, container name and blob name. Consider updating the URL generation code to use the same values.
UriBuilder fulluri = new UriBuilder()
{
Scheme = "https",
Host = string.Format("{0}.blob.core.windows.net", accountname),
Path = string.Format("{0}/{1}", containerName, imageData.fileName),
Query = sastoken
};
Hope this helps.
Upvotes: 1