【发布时间】:2014-09-03 17:15:29
【问题描述】:
我从 Web API 服务中间接调用 CloudBlobContainer.CreateIfNotExist(请参阅下面的 FindOrCreatePrivateBlobContainer 方法),但它返回以下 403 禁止错误消息:
<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;
}
我需要一些帮助来解决此错误的原因。我尝试了以下方法:
- 检查了要创建的容器的名称是否有效,并且在这种特定情况下仅包含小写字母(没有特殊或大写字符)。
- 我了解到 Azure 服务器和调用服务器之间的时区差异会导致 403 禁止错误消息。无论我是从我的个人计算机(时区设置为 UTC)还是从 Azure 部署运行服务,都会发生此错误。
- 我检查了我的连接字符串和帐户密钥,这似乎是正确的。格式如下:
<add key="MyStuff.DocumentManagement.ConnectionString" value="DefaultEndpointsProtocol=http;AccountName=MyStuffAccount;AccountKey=[obfuscated]" /> - 我试过在http和https之间切换,结果没有区别。
- 我可以确认我运行的是最新版本的 Azure 存储 API (4.1.0)
- 我可以通过 VS 2013 服务器资源管理器连接到 Azure 存储并创建一个新容器
请帮忙!
更新
这是启用跟踪后的错误输出:应用程序: 2014-07-13T19:08:03 PID[6888] 错误
Microsoft.WindowsAzure.Storage.StorageException:远程服务器 返回错误:(403)禁止。 ---> System.Net.WebException: 远程服务器返回错误:(403)禁止。应用:在 System.Net.HttpWebRequest.GetResponse() 应用程序:在 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 策略, OperationContext operationContext) 应用:在 Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.Exists(布尔 primaryOnly、BlobRequestOptions requestOptions、OperationContext operationContext) 应用程序:在 Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.CreateIfNotExists(BlobContainerPublicAccessType accessType、BlobRequestOptions requestOptions、OperationContext operationContext) 应用程序:在 [混淆].DocumentManagement.BlobStorage.BlobHelper.FindOrCreatePrivateBlobContainer(String ContainerName, String AccountConnectionString) 应用程序:在 [混淆].DocumentManagement.BlobStorage.BlobFileItemHandler.GetStream(Int64 FileItemId) 应用程序:请求信息应用程序: 请求ID:fce980ad-a673-4ef1-b55d-d017a49845c8 应用: 申请日期:2014 年 7 月 13 日星期日 19:08:02 GMT 申请: StatusMessage:服务器未能验证请求。确保 Authorization 标头的值正确形成,包括 签名。
【问题讨论】:
-
您是否能够使用上述代码中使用的相同密钥从 VS 2013 资源管理器访问存储帐户?如果没有,您能否从门户登录并确认您的密钥尚未重新生成。否则,为了帮助进一步调试,您可以运行 fiddler 并在失败发生时共享您的请求的 fiddler 跟踪。
-
@VinayShah-Microsoft 谢谢,这实际上正是问题所在 - 但是我几天前已经解决了这个问题(只是没有时间在这里更新答案)。此密钥生成是否自动发生?
-
很高兴知道您的问题已解决。密钥重新生成不应自动发生。需要通过门户或服务管理api手动调用。
-
@VinayShah-Microsoft 谢谢。当您凌晨 2 点还在工作时,往往会发生奇怪的事情。
标签: c# asp.net azure-storage