title: List files user has read access to (ASP.NET)
body: <p>I am wanting to list all the files in a folder that a user has read access to. The user visits the website and can use Forms Authentication for some aspects of the site (e.g. adding links etc), but I want to list files in a given folder using their Windows Credentials (since I have anonymous access turned off), hiding those they can't read.</p>
  
  <p>However, when using <code>Directory.GetFiles</code>, it also includes files that can't be read (although the meta data (file size, creation date etc) can be read).</p>
  
  <p>This is what I have:</p>
  
  <pre><code>string[] files;
  string[] folders;
  string rootDir = @"\\server\path\to\dir\";
  WindowsIdentity id = (WindowsIdentity)User.Identity ;
  using (System.Security.Principal.WindowsImpersonationContext context = System.Security.Principal.WindowsIdentity.Impersonate(id.Token))
  {
          files = Directory.GetFiles(rootDir);
          folders = Directory.GetDirectories(rootDir);
  
          foreach (string file in files)
          {
              FileInfo fi = new FileInfo(file);
              FileSecurity fs = fi.GetAccessControl(AccessControlSections.Access);
              //foreach (FileSystemAccessRule rule in fs.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier)))
              //{
              //  Response.Write((FileSystemRights.Read &amp; rule.FileSystemRights) + " &lt;br /&gt;");
              //}
  
              Response.Write(file + " " + fi.Length + "&lt;br /&gt;");
          }
          context.Undo();
  }
  </code></pre>
  
  <p>When I visit the page, I get <code>UnauthorizedAccessException</code> as soon as as I use <code>GetAccessControl</code>, even though it should be using the current user credentials. Taking the <code>using</code> off fails as the asp.net account does not have access to the folder. When <code>FileSecurity</code> is commented out, it lists all the files.</p>
  
  <p>Stack Trace:</p>
  
  <pre><code>[UnauthorizedAccessException: Attempted to perform an unauthorized operation.]
     System.Security.AccessControl.Win32.GetSecurityInfo(ResourceType resourceType, String name, SafeHandle handle, AccessControlSections accessControlSections, RawSecurityDescriptor&amp; resultSd) +697
     System.Security.AccessControl.NativeObjectSecurity.CreateInternal(ResourceType resourceType, Boolean isContainer, String name, SafeHandle handle, AccessControlSections includeSections, Boolean createByName, ExceptionFromErrorCode exceptionFromErrorCode, Object exceptionContext) +63
     System.Security.AccessControl.FileSystemSecurity..ctor(Boolean isContainer, String name, AccessControlSections includeSections, Boolean isDirectory) +86
     System.Security.AccessControl.FileSecurity..ctor(String fileName, AccessControlSections includeSections) +42
     System.IO.FileInfo.GetAccessControl(AccessControlSections includeSections) +29
     UNCDirectory.Page_Load(Object sender, EventArgs e) +213
     System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
     System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
     System.Web.UI.Control.OnLoad(EventArgs e) +99
     System.Web.UI.Control.LoadRecursive() +50
     System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627
  </code></pre>
  
  <p>Any ideas of how I can do this, without resorting to trying to open each file and catching the exception that occurs?</p>