2010-02-05 2 views
2

사용자가 읽기 권한이있는 폴더의 모든 파일을 나열하려고합니다. 사용자가 웹 사이트를 방문하고 사이트의 일부 측면 (예 : 링크 추가 등)에 양식 인증을 사용할 수 있지만 익명 액세스가 해제 된 이후로 Windows 자격 증명을 사용하여 특정 폴더의 파일을 나열하고 숨길 수 있습니다 읽을 수 없습니다.사용자에게 읽기 권한이있는 파일 나열 (ASP.NET)

그러나 Directory.GetFiles을 사용할 때 메타 데이터 (파일 크기, 생성 날짜 등)를 읽을 수는 있지만 읽을 수없는 파일도 포함됩니다.

이 내가 가진 것입니다 : 내가 페이지를 방문 할 때

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 & rule.FileSystemRights) + " <br />"); 
      //} 

      Response.Write(file + " " + fi.Length + "<br />"); 
     } 
     context.Undo(); 
} 

, 나는 그것이 현재 사용자의 자격 증명을 사용해야에도 불구하고, 최대한 빨리 GetAccessControl을 사용뿐만 UnauthorizedAccessException를 얻을. using을 끄면 asp.net 계정에 폴더에 대한 액세스 권한이 없으므로 실패합니다. FileSecurity이 주석 처리되면 모든 파일이 나열됩니다.

스택 추적 : 각 파일을 열려고 및 발생하는 예외를 잡기에 의지하지 않고 내가이 작업을 수행 할 수있는 방법

[UnauthorizedAccessException: Attempted to perform an unauthorized operation.] 
    System.Security.AccessControl.Win32.GetSecurityInfo(ResourceType resourceType, String name, SafeHandle handle, AccessControlSections accessControlSections, RawSecurityDescriptor& 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 

어떤 아이디어?

답변

2

고칠 수 있도록 관리했습니다. 파일에 대한 읽기를 거부하면 읽기 권한도 거부되므로 UnauthorizedAccessException입니다. 따라서 try... catch ...을 사용하는 것이 유일한 옵션 인 것처럼 보입니다.

Read가 거부되고 ReadPermissions가 허용되는 경우 (Advance 설정에서 수행됨) 예외를 방지 할 수 있습니다. 이것은 모두 처리합니다

이제 파일이 아니라 ASP.NET 계정 (일반적으로 네트워크 서비스)에 대한 액세스 권한을 부여하지 않고 (가장을 사용하여) 임의의 디렉토리에 나열 할 수 있습니다
string[] files; 
string[] folders; 
WindowsIdentity id = (WindowsIdentity)User.Identity; 
using (System.Security.Principal.WindowsImpersonationContext context = id.Impersonate()) 
{ 
    files = Directory.GetFiles(RootDir); 
    folders = Directory.GetDirectories(RootDir); 

    foreach (string file in files) 
    { 
     FileInfo fi = new FileInfo(file); 
     FileSecurity fs = null; 
     try 
     { 
      fs = fi.GetAccessControl(AccessControlSections.Access); 
     } 
     catch (UnauthorizedAccessException) 
     { 
      goto Next; 
     } 
     foreach (FileSystemAccessRule rule in fs.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))) 
     { 
      if (id.User.CompareTo(rule.IdentityReference as SecurityIdentifier) == 0) 
      { 
       if(rule.AccessControlType.ToString() == "Deny" && 
        rule.FileSystemRights.ToString().Contains("ReadData")) 
       { 
        goto Next; 
       } 
      } 
     } 

     Response.Write(file + " " + fi.Length + "<br />"); 
     // next in sequence. label for goto 
     Next: ; 
    } 
    context.Undo(); 
} 

.

+2

나는 nitpick ...을 싫어하지만 왜 goto와 라벨을 사용하고 있습니까? 필요한 경우 휴식하거나 계속하십시오. –

+0

시도해 보았지만 FileAccessRule foreach만을 깨뜨린 것입니다.이 파일에서 벗어나 다음 파일로 계속 진행하려고했습니다. 나는 bool이 사용될 수 있다고 생각하지만 ... 라벨은 사용하기 좋지 않다. 그렇다면 왜 안 되니? – SamWM

+2

Goto는 중첩 루프를 제거하는 데 유용합니다. 각 루프 수준에서 불필요한 조건부 중단을 피함으로써 많은 경우 논리를 단순화하고 성능을 향상시킵니다. – Triynko

1

아마도 asp.net/IIS에서 Windows/통합 인증을 설정해야합니다. http://msdn.microsoft.com/en-us/library/aa292114(VS.71).aspx

+0

이 사이트는 통합 인증을 사용하고 있으며 실제로 보여지는 파일 목록을 검색 할 수 있습니다 (그렇지 않으면 예외가 발생합니다 - 내가 얻는 것과 다릅니다). 파일에 대한 액세스 규칙을 얻으려고 할 때 오류가 발생합니다. – SamWM

관련 문제