2

ユーザーが読み取りアクセス権を持つフォルダー内のすべてのファイルを一覧表示したいと考えています。ユーザーは Web サイトにアクセスし、サイトの一部の側面 (リンクの追加など) にフォーム認証を使用できますが、Windows 資格情報を使用して特定のフォルダー内のファイルを一覧表示したい (匿名アクセスがオフになっているため)。読めません。

ただし、 を使用する場合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();
}

ページにアクセスすると、現在のユーザー資格情報を使用する必要があるにもかかわらず、UnauthorizedAccessException使用するとすぐに取得されます。asp.net アカウントにはフォルダーへのアクセス権がないためGetAccessControl、オフにできません。コメントアウトすると、すべてのファイルが一覧表示されますusingFileSecurity

スタックトレース:

[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

各ファイルを開こうとして発生する例外をキャッチすることに頼らずに、これを行う方法についてのアイデアはありますか?

4

2 に答える 2

2

それを修正することができました。ファイルの読み取りを拒否すると、読み取り権限も拒否されるため、UnauthorizedAccessException. したがって、それを使用try... catch ...することが唯一のオプションのように見えます。

Read が拒否され、ReadPermissions が許可されている場合 (詳細設定で実行)、例外を防ぐことができます。これは両方を処理します:

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();
}

ASP.NET アカウント (通常はネットワーク サービス) にアクセス権を与えることなく、(偽装を使用して) 任意のディレクトリにファイルを一覧表示できるようになりました。

于 2010-02-19T15:22:59.527 に答える
1

おそらく、asp.net/IISでWindows/統合認証を設定する必要があります。http://msdn.microsoft.com/en-us/library/aa292114(VS.71).aspx

于 2010-02-05T18:06:52.583 に答える