Reputation: 2221
I am calling CloudBlobContainer.CreateIfNotExist (see FindOrCreatePrivateBlobContainer method below) indirectly from within a Web API service, but it returns the following 403 forbidden error message:
<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>
Here is the code that is generating the 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;
}
I need some help as to troubleshoot the cause of this error. I have tried the following:
<add key="MyStuff.DocumentManagement.ConnectionString" value="DefaultEndpointsProtocol=http;AccountName=MyStuffAccount;AccountKey=[obfuscated]" />
Please help!
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](RESTCommand
1 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.
Upvotes: 11
Views: 19467
Reputation: 11
Try the following: 1. Generate new access keys to use in your App.config file
OR 2. Login into your azure portal Under storage account Select ->Firewalls and virtual networks --> Under the blade, Enable Allow access from "All Networks" Option
I hope this works for someone!
Upvotes: 1
Reputation: 47
I had a similar issue when trying to connect to my local azure storage emulator. Through Azure Storage explorer the connection was successful but through a custom tool which uses REST API it was throwing 403 error. I had to manually include endpoints in the config and use http instead https.
More on that here (https://learn.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string)
DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;
AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;
BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;
TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;
QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;
Upvotes: 1
Reputation: 563
For me, it turned out that we had an IP restriction on the storage account which was causing a 403 Forbidden. The way to fix it was to access the Azure Portal and go to:
Storage Accounts → "StorageAccountName" → Firewalls and Virtual Networks
And then make sure that your IP is in the allowed section, or check "Allow access from All Networks".
Upvotes: 1
Reputation: 81
I saw the same error message when calling
Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient.GetBlobReferenceFromServerAsync(Uri blobUri)
accidentally using a blobUri value that pointed to a different URL than the CloudBlobClient.BaseUri
was pointing to.
Upvotes: 0
Reputation: 271
This may not be the solution to this particular problem, but it might help someone else.
I was getting a 403 error and had a hard time tracking down the solution. I finally figured out that my development machine's time was off by 2 hours. When I set the time correctly, the 403 went away.
Azure requires the UTC timestamp to be within 15 minutes of the request time.
Upvotes: 27
Reputation: 3082
If you have recently upgraded your WindowsAzure.Storage instead of using the deprecated WindowsAzure.StorageClient dll then you could be experiencing this issue as the BlobRequestOptions and OperationContext have not been set
MSDN Link with CloudBlobContainer Create If Not Exists Method
Upvotes: 2
Reputation: 332
As we discussed in comments above, please make sure your keys valid when you start getting 403 status code back from the service. Keys can change if they have been re-generated through the portal or using service management API's
Upvotes: 6