下载存储Blob时如何解决“ KeyVaultErrorException:操作返回了无效的状态码'Forbidden'”

时间:2019-08-29 08:34:21

标签: c# azure-storage-blobs azure-keyvault

我收到KeyVaultErrorException:当我尝试下载存储Blob(DownloadToStream)时,操作返回了无效的状态码'Forbidden'。

我尝试创建另一个rsa密钥。但是发生了同样的错误。 当我使用一个秘密。一切都很好。 我检查了密钥库访问策略。 用户帐户具有完全权限。 该应用程序具有密钥和机密的获取和列出权限。

这是完整的代码。 它基于此sample

using System;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Configuration;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.Azure.KeyVault;
using System.Threading;
using System.IO;

namespace KeyVaultTest
{
   class Program
   {
      static void Main(string[] args)
      {
         // This is standard code to interact with Blob Storage
         StorageCredentials creds = new StorageCredentials(
             ConfigurationManager.AppSettings["accountName"],
             ConfigurationManager.AppSettings["accountKey"]);
         CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true);
         CloudBlobClient client = account.CreateCloudBlobClient();
         CloudBlobContainer contain = client.GetContainerReference("test123");
         contain.CreateIfNotExists();

         // The Resolver object is used to interact with Key Vault for Azure Storage
         // This is where the GetToken method from above is used
         KeyVaultKeyResolver cloudResolver = new KeyVaultKeyResolver(GetToken);

         // Retrieve the key that you created previously
         // The IKey that is returned here is an RsaKey
         // Remember that we used the names contosokeyvault and testrsakey1
         var rsa = cloudResolver.ResolveKeyAsync("https://mykeystorage.vault.azure.net/keys/testkey9000/", CancellationToken.None).GetAwaiter().GetResult();


         // Now you simply use the RSA key to encrypt by setting it in the BlobEncryptionPolicy. 
         BlobEncryptionPolicy policy = new BlobEncryptionPolicy(rsa, null);
         BlobRequestOptions options = new BlobRequestOptions() { EncryptionPolicy = policy };

         // Reference a block blob
         CloudBlockBlob blob = contain.GetBlockBlobReference("MyFile.txt");

         // Upload using the UploadFromStream method
         using (var stream = System.IO.File.OpenRead(@"C:\temp\MyFile.txt"))
            blob.UploadFromStream(stream, stream.Length, null, options, null);


         // In this case we will not pass a key and only pass the resolver because 
         //  this policy will only be used for downloading / decrypting
         policy = new BlobEncryptionPolicy(null, cloudResolver);
         options = new BlobRequestOptions() { EncryptionPolicy = policy };

         using (var np = File.Open(@"C:\temp\MyFileDecrypted.txt", FileMode.Create))
            blob.DownloadToStream(np, null, options, null);
      }

      private async static Task<string> GetToken(string authority, string resource, string scope)
      {
         var authContext = new AuthenticationContext(authority);
         ClientCredential clientCred = new ClientCredential(
             ConfigurationManager.AppSettings["clientId"],
             ConfigurationManager.AppSettings["clientSecret"]);
         AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);

         if (result == null)
            throw new InvalidOperationException("Failed to obtain the JWT token");

         return result.AccessToken;
      }
   }
}

1 个答案:

答案 0 :(得分:0)

如果要访问密钥库资源,则需要为AD应用程序配置访问策略,并使其具有足够的权限来访问密钥库资源。有关更多详细信息,请参阅Azure key vault: access denied