Chr*_*s B 179 c# directory permissions
我需要测试用户是否可以在实际尝试之前写入文件夹.
我已经实现了以下方法(在C#2.0中),它尝试使用Directory.GetAccessControl()方法检索文件夹的安全权限.
private bool hasWriteAccessToFolder(string folderPath)
{
try
{
// Attempt to get a list of security permissions from the folder.
// This will raise an exception if the path is read only or do not have access to view the permissions.
System.Security.AccessControl.DirectorySecurity ds = Directory.GetAccessControl(folderPath);
return true;
}
catch (UnauthorizedAccessException)
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
当我在谷歌搜索如何测试写入访问时,没有出现这样的情况,实际测试Windows中的权限似乎非常复杂.我担心我过度简化了事情并且这种方法并不健全,尽管它似乎确实有效.
我的方法是否可以测试当前用户是否具有写访问权限?
Dun*_*owe 62
我很欣赏这篇帖子的当天晚些时候,但您可能会发现这段代码很有用.
string path = @"c:\temp";
string NtAccountName = @"MyDomain\MyUserOrGroup";
DirectoryInfo di = new DirectoryInfo(path);
DirectorySecurity acl = di.GetAccessControl(AccessControlSections.All);
AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(NTAccount));
//Go through the rules returned from the DirectorySecurity
foreach (AuthorizationRule rule in rules)
{
//If we find one that matches the identity we are looking for
if (rule.IdentityReference.Value.Equals(NtAccountName,StringComparison.CurrentCultureIgnoreCase))
{
var filesystemAccessRule = (FileSystemAccessRule)rule;
//Cast to a FileSystemAccessRule to check for access rights
if ((filesystemAccessRule.FileSystemRights & FileSystemRights.WriteData)>0 && filesystemAccessRule.AccessControlType != AccessControlType.Deny)
{
Console.WriteLine(string.Format("{0} has write access to {1}", NtAccountName, path));
}
else
{
Console.WriteLine(string.Format("{0} does not have write access to {1}", NtAccountName, path));
}
}
}
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)
将其放入控制台应用程序,看看它是否满足您的需求.
小智 58
public bool IsDirectoryWritable(string dirPath, bool throwIfFails = false)
{
try
{
using (FileStream fs = File.Create(
Path.Combine(
dirPath,
Path.GetRandomFileName()
),
1,
FileOptions.DeleteOnClose)
)
{ }
return true;
}
catch
{
if (throwIfFails)
throw;
else
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
JGU*_*JGU 21
我尝试了大部分这些,但是它们给出了误报,所有这些都是出于同样的原因.仅仅测试目录的可用权限是不够的,你必须检查登录用户是否是具有该权限的组的成员允许.为此,您将获得用户标识,并检查它是否是包含FileSystemAccessRule IdentityReference的组的成员.我测试了这个,完美无缺地工作..
/// <summary>
/// Test a directory for create file access permissions
/// </summary>
/// <param name="DirectoryPath">Full path to directory </param>
/// <param name="AccessRight">File System right tested</param>
/// <returns>State [bool]</returns>
public static bool DirectoryHasPermission(string DirectoryPath, FileSystemRights AccessRight)
{
if (string.IsNullOrEmpty(DirectoryPath)) return false;
try
{
AuthorizationRuleCollection rules = Directory.GetAccessControl(DirectoryPath).GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
WindowsIdentity identity = WindowsIdentity.GetCurrent();
foreach (FileSystemAccessRule rule in rules)
{
if (identity.Groups.Contains(rule.IdentityReference))
{
if ((AccessRight & rule.FileSystemRights) == AccessRight)
{
if (rule.AccessControlType == AccessControlType.Allow)
return true;
}
}
}
}
catch { }
return false;
}
Run Code Online (Sandbox Code Playgroud)
UGE*_*EEN 13
例如,对于所有用户(Builtin\Users),此方法工作正常 - 享受.
public static bool HasFolderWritePermission(string destDir)
{
if(string.IsNullOrEmpty(destDir) || !Directory.Exists(destDir)) return false;
try
{
DirectorySecurity security = Directory.GetAccessControl(destDir);
SecurityIdentifier users = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
foreach(AuthorizationRule rule in security.GetAccessRules(true, true, typeof(SecurityIdentifier)))
{
if(rule.IdentityReference == users)
{
FileSystemAccessRule rights = ((FileSystemAccessRule)rule);
if(rights.AccessControlType == AccessControlType.Allow)
{
if(rights.FileSystemRights == (rights.FileSystemRights | FileSystemRights.Modify)) return true;
}
}
}
return false;
}
catch
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
试试这个:
try
{
DirectoryInfo di = new DirectoryInfo(path);
DirectorySecurity acl = di.GetAccessControl();
AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(NTAccount));
WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(currentUser);
foreach (AuthorizationRule rule in rules)
{
FileSystemAccessRule fsAccessRule = rule as FileSystemAccessRule;
if (fsAccessRule == null)
continue;
if ((fsAccessRule.FileSystemRights & FileSystemRights.WriteData) > 0)
{
NTAccount ntAccount = rule.IdentityReference as NTAccount;
if (ntAccount == null)
{
continue;
}
if (principal.IsInRole(ntAccount.Value))
{
Console.WriteLine("Current user is in role of {0}, has write access", ntAccount.Value);
continue;
}
Console.WriteLine("Current user is not in role of {0}, does not have write access", ntAccount.Value);
}
}
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("does not have write access");
}
Run Code Online (Sandbox Code Playgroud)
您的代码获取DirectorySecurity给定目录,并正确处理异常(由于您无法访问安全信息).但是,在您的示例中,您实际上并不询问返回的对象以查看允许访问的内容 - 我认为您需要添加此内容.
这是CsabaS答案的修改版本,它解释了明确的拒绝访问规则.该函数遍历目录的所有FileSystemAccessRules,并检查当前用户是否具有可访问目录的角色.如果未找到此类角色或用户处于拒绝访问的角色,则该函数返回false.要检查读取权限,请将FileSystemRights.Read传递给该函数; 对于写权限,传递FileSystemRights.Write.如果要检查任意用户的权限而不是当前用户的权限,请将currentUser WindowsIdentity替换为所需的WindowsIdentity.我还建议不要依赖这样的函数来确定用户是否可以安全地使用该目录.这个答案完美地解释了原因
public static bool UserHasDirectoryAccessRights(string path, FileSystemRights accessRights)
{
var isInRoleWithAccess = false;
try
{
var di = new DirectoryInfo(path);
var acl = di.GetAccessControl();
var rules = acl.GetAccessRules(true, true, typeof(NTAccount));
var currentUser = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(currentUser);
foreach (AuthorizationRule rule in rules)
{
var fsAccessRule = rule as FileSystemAccessRule;
if (fsAccessRule == null)
continue;
if ((fsAccessRule.FileSystemRights & accessRights) > 0)
{
var ntAccount = rule.IdentityReference as NTAccount;
if (ntAccount == null)
continue;
if (principal.IsInRole(ntAccount.Value))
{
if (fsAccessRule.AccessControlType == AccessControlType.Deny)
return false;
isInRoleWithAccess = true;
}
}
}
}
catch (UnauthorizedAccessException)
{
return false;
}
return isInRoleWithAccess;
}
Run Code Online (Sandbox Code Playgroud)
以上解决方案很好,但对我来说,我发现这段代码简单可行。只需创建一个临时文件。如果创建了文件,则其平均用户具有写访问权限。
public static bool HasWritePermission(string tempfilepath)
{
try
{
System.IO.File.Create(tempfilepath + "temp.txt").Close();
System.IO.File.Delete(tempfilepath + "temp.txt");
}
catch (System.UnauthorizedAccessException ex)
{
return false;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
我使用相同的函数检查文件是否hasWriteAccess:
private static bool HasWriteAccessToFile(string filePath)
{
try
{
// Attempt to get a list of security permissions from the file.
// This will raise an exception if the path is read only or do not have access to view the permissions.
File.GetAccessControl(filePath);
return true;
}
catch (UnauthorizedAccessException)
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)