I have to sync down blobs from Azure into each server for our custom C# CMS I'm writing. (we're planning on servers in different locations) I am creating a local directory on each server to hold 'research articles' content'. that works fine. setting permissions for it, works fine. However, upon calling .DownloadToFile(...) on Azure's 'CloudBlockBlob' hits the permission error.
My code is smart enough to get the appPoolIdentity name and use that to set permissions. but am I setting what's needed?...
// === Get body content from Azure blobs ===
// 1. if local directory doesn't exist, create it
var localdirectory =
ConfigurationManager.AppSettings["ResearchArticleBodyRelativeLocalDirectory"] +
researchArticle.BodyRelativeLocalPath;
var exists = System.IO.Directory.Exists(Server.MapPath(localdirectory));
if (!exists)
{
// 2a. if it didn't exist, create it, set write perms, and pull azure blobs
// create
System.IO.Directory.CreateDirectory(Server.MapPath(localdirectory));
// --perms--
// get user for app
var info = new DirectoryInfo(Server.MapPath(localdirectory));
var security = info.GetAccessControl();
var appPoolName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
security.AddAccessRule(new FileSystemAccessRule(appPoolName, FileSystemRights.Modify, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));
security.AddAccessRule(new FileSystemAccessRule(appPoolName, FileSystemRights.Modify, InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); //(I've tried 'write' as well)
info.SetAccessControl(security);
// pull blobs
Azure.GetBlobsFromAzureByContainerName(researchArticle);
}
else
{
// 2b. If it does exist, check/compare lastModifiedDate and pull blobs if necessary
if (Azure.ContainerNewerThanLocal(researchArticle))
Azure.GetBlobsFromAzureByContainerName(researchArticle);
}
Here's the static 'Azure' class:
public static List<CloudBlockBlob> GetBlobsFromAzureByContainerName(ResearchArticle researchArticle)
{
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
ConfigurationManager.AppSettings["StorageConnectionString"]);
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve a reference to a container.
CloudBlobContainer container = blobClient.GetContainerReference(researchArticle.BodyAzureContainerName);
List<CloudBlockBlob> contentBlobList = new List<CloudBlockBlob>();
// TODO: Delete everything in local directory ..?
System.IO.DirectoryInfo downloadedMessageInfo = new DirectoryInfo(HostingEnvironment.MapPath(ConfigurationManager.AppSettings["ResearchArticleBodyRelativeLocalDirectory"] +
researchArticle.BodyRelativeLocalPath));
foreach (FileInfo file in downloadedMessageInfo.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in downloadedMessageInfo.GetDirectories())
{
dir.Delete(true);
}
// Loop over items within the container and output the length and URI.
foreach (IListBlobItem item in container.ListBlobs(null, false))
{
if (item.GetType() == typeof(CloudBlockBlob))
{
CloudBlockBlob blockBlob = (CloudBlockBlob)item;
*explodes here-->blockBlob.DownloadToFile(HostingEnvironment.MapPath(
ConfigurationManager.AppSettings["ResearchArticleBodyRelativeLocalDirectory"] +
researchArticle.BodyRelativeLocalPath), FileMode.Create);
FYI: I even manually set the permissions on the folder using 'NETWORK_SERVICE', 'IIS_IUSRS', and 'IIS_WPG' all set to write and then full control... then I tried 'Everyone' set to full control to no avail... not sure what is going on. I'm in an active directory here, so that might be an issue?
there is no authentication on the public side/site, all anonymous.
<authentication mode="None" />
<authorization>
<allow users="?" />
</authorization>
Could this be a part of the issue? Web.config saying all anonymous, but then setting NTFS perms on sub-folders causes a problem?
The error I am getting is always:
Access to the path 'C:\...\ResearchArticleBodyLocal\abc' is denied.
via
Chebli Mohamed