17
votes

Comment obtenir une signature d'accès partagé sur un objet blob à l'aide de la dernière API Azure SDK .NET v12?

Avant, je pouvais créer une signature d'accès partagé sur un objet blob à l'aide de l'API Azure SDK v11, comme ceci:

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);

...

Je souhaite utiliser la dernière API v12 .NET qui semble remplacer CloudBlobClient par BlobServiceClient , CloudBlobContainer par BlobContainerClient et CloudBlockBlob par BlobClient .

Cependant, la méthode GetSharedAccessSignature qui est disponible sur une instance CloudBlockBlob n'est pas disponible sur une instance BlobClient .

Question

Comment obtenir une signature d'accès partagé à partir d'une instance BlobClient à l'aide de la dernière API Azure SDK .NET v12?


0 commentaires

6 Réponses :


24
votes

La réponse de Sajeetharan m'a fait chercher une classe BlobSasBuilder , qui existe réellement.

Voici comment je peux en créer un sur le serveur:

//  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);

Voici comment l'utiliser côté client:

//  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);

Addenda

Comme mentionné par @ one2012 dans les commentaires, une page a été mise en place quelques mois plus tard après cette réponse présentant toutes les fonctionnalités trouvées dans les espaces de noms Azure.Storage. Le lien peut être utile pour obtenir plus d'informations.


4 commentaires

Je ne peux pas trouver un moyen d'obtenir le storageSharedKeyCredential à partir de la chaîne de connexion au lieu d'utiliser le AccountName et AccountKey. Savez-vous quoi que ce soit?


@benjamin var csBuilder = new DbConnectionStringBuilder(); csBuilder.ConnectionString = _configuration.GetConnectionString("MyCS"); var storageSharedKeyCredential = new StorageSharedKeyCredential( (string)csBuilder["AccountName"], (string)csBuilder["AccountKey"]);


si vous passez à Azure.Storage namespaces cette page est la chose la plus utile que j'ai trouvée craftedforeveryone.com/...


vous, monsieur, avez sauvé ma vie et ma santé mentale



0
votes

À l'aide de la bibliothèque cliente de stockage Azure Blob v12 pour .NET:

        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();


0 commentaires

0
votes
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();
}
The above is my working code.However, I can't work out how to create a stored access policy with V12. It should be this: https://docs.microsoft.com/en-us/dotnet/api/azure.storage.blobs.blobcontainerclient.setaccesspolicy?view=azure-dotnet But I think Microsoft have completely forgotten to provide a way to create BlobSignedIdentifier. The docs are out of date: https://docs.microsoft.com/en-us/azure/storage/common/storage-stored-access-policy-define-dotnet?toc=%2fazure%2fstorage%2fblobs%2ftoc.jsonWhich uses Microsoft.Azure.Storage.Blob, but https://www.nuget.org/packages/Microsoft.Azure.Storage.Blob/ says don't use it anymore.

0 commentaires

3
votes

Après pas mal de recherches, j'ai trouvé de la documentation Microsoft à ce sujet: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet

Cela détaille l'utilisation d'une clé de délégation utilisateur pour générer le SAS au lieu de la clé de compte, mais le changement est juste une surcharge différente de .ToSasQueryParameters () comme décrit dans d'autres réponses.

Quelques extraits clés de l'article pour connecter cela. Créez d'abord votre BlobServiceClient:

// 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
};

Obtenez la clé de délégation de l'utilisateur, elle sera utilisée pour générer le 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));

Enfin, créez l'URI SAS:

// 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());


0 commentaires

0
votes

À l'aide de la bibliothèque cliente de stockage Azure Blob v12 pour .NET:

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();

Dans le cas où la signature d'accès partagé (jeton SAS) doit être générée en fonction de la stratégie d'accès attribuée à un conteneur, utilisez la méthode ci-dessous

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();

Remarque: Lorsque la génération de jetons SAS est basée sur la stratégie d'accès attribuée au conteneur, vous ne pourrez pas définir les autorisations, l'heure de début ou de fin dans BlobSasBuilder. Vous obtiendrez une exception d'exécution car "Les champs de stratégie d'accès peuvent être associés à la signature ou à l'identifiant SAS mais pas aux deux"

Référence: 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


0 commentaires

0
votes

Ici: https://docs.microsoft.com/en-us/rest/api/storageservices/delegate-access-with-shared-access-signature indique qu'Azure Storage prend en charge trois types différents de signature d'accès partagé (SAS) :

  1. SAS au niveau du compte, ce que vous utilisiez dans le SDK v11. Détails et exemple ici: https://docs.microsoft.com/en-us/azure/storage/common/storage-account-sas-create-dotnet
  2. SAS de niveau de service, utilisant le SDK v12 (et V11). Détails et exemple ici: https://docs.microsoft.com/en-us/azure/storage/blobs/sas-service-create?tabs=dotnet
  3. La délégation d'utilisateurs SAS, qui est l'approche recommandée par Microsoft, à condition que vous puissiez utiliser un utilisateur Azure Active Directory pour vous connecter à l'aide du SDK v12. Détails et exemple ici: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet

1 et 2 utilisent tous deux la clé partagée du compte pour générer le jeton SAS, tandis que 3 utilise une clé générée à partir de l'utilisateur du compte AAD, ce qui est plus sûr et plus facilement ciblable pour une révocation si nécessaire (en théorie). Voir https://docs.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas#:~:text=Authorization%20of%20a%20user%20delegation%20SAS,-When%20a % 20client & text = Cette% 20approach% 20 fournit% 20an% 20 supplémentaire, est% 20a% 20security% 20best% 20pratique . pour plus de détails sur les raisons pour lesquelles cela est plus sécurisé ("Cette approche offre un niveau de sécurité supplémentaire et évite de devoir stocker la clé d'accès de votre compte avec le code de votre application. Pour ces raisons, la création d'un SAS à l'aide des informations d'identification Azure AD est une bonne pratique de sécurité . ")

Maintenant, tous sont pris en charge par le compte de stockage à utiliser , mais j'ai l'impression que le niveau du compte n'est pas non plus pris en charge à implémenter dans le SDK v12 (je suppose - alors ne me citez pas, mais je ne le trouve pas non plus ) ou il existe un autre moyen caché de le faire (certainement la méthode BlobSasBuilder.ToSasQueryParameters () n'a que les deux surcharges), ce qui, je suppose, laisse la délégation de l'utilisateur ou les approches de niveau de service comme ce que vous êtes maintenant censé implémenter.


0 commentaires