我想列出用户具有读取权限的文件夹中的所有文件。用户访问网站,可以使用表单身份验证的一些方面(例如添加链接等),但我想使用他们的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
后立即获得GetAccessControl
。取消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
有关如何执行此操作的任何想法,而不是尝试打开每个文件并捕获发生的异常?
答案 0 :(得分: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帐户(通常是网络服务)访问。
答案 1 :(得分:1)
您可能需要在asp.net/IIS中设置Windows /集成身份验证。 http://msdn.microsoft.com/en-us/library/aa292114(VS.71).aspx