c# - Azure CloudBlobContainer.CreateIfNotExists 返回 403 forbidden

标签 c# asp.net azure-storage

我从 Web API 服务中间接调用 CloudBlobContainer.CreateIfNotExist(请参阅下面的 FindOrCreatePrivateBlobContainer 方法),但它返回以下 403 forbidden 错误消息:

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The remote server returned an error: (403) Forbidden.
</ExceptionMessage>
<ExceptionType>Microsoft.WindowsAzure.Storage.StorageException</ExceptionType>
<StackTrace>
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.Exists(Boolean primaryOnly, BlobRequestOptions requestOptions, OperationContext operationContext) at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.CreateIfNotExists(BlobContainerPublicAccessType accessType, BlobRequestOptions requestOptions, OperationContext operationContext) at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.CreateIfNotExists(BlobRequestOptions requestOptions, OperationContext operationContext) at [Obfuscated].DocumentManagement.BlobStorage.BlobHelper.FindOrCreatePrivateBlobContainer(String ContainerName, String AccountConnectionString) in c:\Users\[Obfuscated]\Desktop\[ProjectNameObfuscated]Online\[Obfuscated].DocumentManagement.BlobStorage\BlobHelper.cs:line 25 at [Obfuscated].DocumentManagement.BlobStorage.BlobFileItemHandler.GetStream(Int64 FileItemId) in c:\Users\[Obfuscated]\Desktop\[ProjectNameObfuscated]Online\[Obfuscated].DocumentManagement.BlobStorage\BlobFileItemHandler.cs:line 114 at [Obfuscated].DocumentManagement.Service.Controllers.FileItemController.Get(String ServiceAuthKey, Int64 FileItemId) in c:\Users\[Obfuscated]\Desktop\[ProjectNameObfuscated]Online\[Obfuscated].DocumentManagement.Service\Controllers\FileItemController.cs:line 148 at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
</StackTrace>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The remote server returned an error: (403) Forbidden.
</ExceptionMessage>
<ExceptionType>System.Net.WebException</ExceptionType>
<StackTrace>
at System.Net.HttpWebRequest.GetResponse() at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext)
</StackTrace>
</InnerException>
</Error>

这是产生错误的代码:

     public HttpResponseMessage Get(string ServiceAuthKey, Int64 FileItemId)
        {
            if (!CheckServiceAuthKey(ServiceAuthKey).IsSuccessStatusCode)
                return new HttpResponseMessage(HttpStatusCode.Unauthorized);

            HttpRequest request = HttpContext.Current.Request;

            FileItem fi = null;
            using (DocumentDbContext db = new DocumentDbContext())
            {
                fi = db.FileItems.Find(FileItemId);
            }


            BlobFileItemHandler fih = new BlobFileItemHandler();
            Stream s = fih.GetStream(FileItemId);


            // -------- DOWNLOAD FILE TO CLIENT -------- 

            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Content = new StreamContent(s);
            //a text file is actually an octet-stream (pdf, etc)
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            //we used attachment to force download
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            response.Content.Headers.ContentDisposition.FileName = fi.PublicFileName;


            return response;
        }

 public Stream GetStream(Int64 FileItemId)
        {
            CloudBlobContainer c = BlobHelper.FindOrCreatePrivateBlobContainer("[Obfuscated]-dms", AccountConnectionString);

            using (DocumentDbContext db = new DocumentDbContext())
            {
                FileItem fi = db.FileItems.Find(FileItemId);

                CloudBlockBlob blob = c.GetDirectoryReference(fi.FilePathOnServer).GetBlockBlobReference(fi.PrivateFileName);
                bool blobExists = blob.Exists();

                if (!blobExists)
                    throw new System.IO.FileNotFoundException();

                Stream stream = new MemoryStream();
                blob.DownloadToStream(stream);
                long streamlen = stream.Length;
                stream.Position = 0;
                return stream;
            }

        }

public static CloudBlobContainer FindOrCreatePrivateBlobContainer(string ContainerName, string AccountConnectionString)
        {
            Trace.TraceInformation("FindOrCreatePrivateBlobContainer '" + ContainerName + "' with connectionstring '" + AccountConnectionString + "'");
            CloudStorageAccount account = CloudStorageAccount.Parse(AccountConnectionString);
            CloudBlobClient blobClient = account.CreateCloudBlobClient();
            CloudBlobContainer container = blobClient.GetContainerReference(ContainerName);
            container.CreateIfNotExists();
            return container;
        }

我需要一些帮助来解决此错误的原因。我尝试了以下方法:

  1. 检查要创建的容器的名称是否有效,并且在这种特定情况下仅包含小写字母(无特殊或大写字符)。
  2. 我了解到 Azure 服务器和调用服务器之间的时区差异会导致 403 禁止错误消息。无论我是从我的个人计算机(时区设置为 UTC)还是从 Azure 部署运行该服务,都会发生此错误。
  3. 我已经检查了我的连接字符串和帐户 key ,这似乎是正确的。它采用以下格式:<add key="MyStuff.DocumentManagement.ConnectionString" value="DefaultEndpointsProtocol=http;AccountName=MyStuffAccount;AccountKey=[obfuscated]" />
  4. 我试过在 http 和 https 之间切换,结果没有区别。
  5. 我可以确认我正在针对最新版本的 Azure 存储 API (4.1.0) 运行
  6. 我能够连接到 Azure 存储并通过 VS 2013 服务器资源管理器创建一个新容器

请帮忙!

更新

Here is the output of the error after I enabled tracing: Application: 2014-07-13T19:08:03 PID[6888] Error
Microsoft.WindowsAzure.Storage.StorageException: The remote server returned an error: (403) Forbidden. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden. Application: at System.Net.HttpWebRequest.GetResponse() Application: at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext) Application: --- End of inner exception stack trace --- Application: at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext) Application: at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.Exists(Boolean primaryOnly, BlobRequestOptions requestOptions, OperationContext operationContext) Application: at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.CreateIfNotExists(BlobContainerPublicAccessType accessType, BlobRequestOptions requestOptions, OperationContext operationContext) Application: at [Obfuscated].DocumentManagement.BlobStorage.BlobHelper.FindOrCreatePrivateBlobContainer(String ContainerName, String AccountConnectionString) Application: at [Obfuscated].DocumentManagement.BlobStorage.BlobFileItemHandler.GetStream(Int64 FileItemId) Application: Request Information Application: RequestID:fce980ad-a673-4ef1-b55d-d017a49845c8 Application: RequestDate:Sun, 13 Jul 2014 19:08:02 GMT Application: StatusMessage:Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

最佳答案

这可能不是这个特定问题的解决方案,但它可能对其他人有帮助。

我遇到了 403 错误并且很难找到解决方案。我终于弄清楚我的开发机器的时间已经关闭了 2 个小时。当我正确设置时间时,403 消失了。

Azure 要求 UTC 时间戳在请求时间的 15 分钟内。

关于c# - Azure CloudBlobContainer.CreateIfNotExists 返回 403 forbidden,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24725514/

相关文章:

c# - 最小起订量工作单位

Azure 数据工厂通过访问 key 连接到 Blob 存储

Azure 存储静态网站错误 - 找不到资源或内容不存在

node.js - 如何使用node js从azure存储中删除文件夹

c# - http工作时如何测试WCF net.tcp?

c# - 从数据行中检索日期时间值 (C#)

c# - Entity Framework 探查器 - ASP.NET MVC4 与 EF 6 - 无法确定提供者名称

c# - LoadViewState 和 SaveViewstate?

c# - 找不到类型或命名空间名称 'Class1'(是否缺少 using 指令或程序集引用?)

asp.net - 如何在 IIS7 中为 HttpHandler 注册多个路径?