在我的.NET 2.0的应用程序,我需要检查是否存在足够的权限来创建和写入文件的目录。 为此,我有以下功能,试图创建一个文件和一个单字节写,删除自身事后测试权限确实存在。
我想检查的最好办法是实际尝试并做到这一点,捕捉发生的任何异常。 我不是特别高兴的一般例外抓了,所以是有这样做的更好或者一个比较公认的方法是什么?
private const string TEMP_FILE = "\\tempFile.tmp";
/// <summary>
/// Checks the ability to create and write to a file in the supplied directory.
/// </summary>
/// <param name="directory">String representing the directory path to check.</param>
/// <returns>True if successful; otherwise false.</returns>
private static bool CheckDirectoryAccess(string directory)
{
bool success = false;
string fullPath = directory + TEMP_FILE;
if (Directory.Exists(directory))
{
try
{
using (FileStream fs = new FileStream(fullPath, FileMode.CreateNew,
FileAccess.Write))
{
fs.WriteByte(0xff);
}
if (File.Exists(fullPath))
{
File.Delete(fullPath);
success = true;
}
}
catch (Exception)
{
success = false;
}
}
Answer 1:
通过这些问题的答案理查德和杰森是那种在正确的方向。 但是你应该做的是计算有效权限运行代码的用户身份。 的实施例中没有正确以上占例如组成员身份。
我敢肯定, 基思·布朗有一些代码在他做这个维基版本的(离线此时) 的.NET开发人员指南,Windows安全 。 这也是在合理的细节在他的讨论编程Windows安全性的书。
计算有效权限是不是一件轻松的事情,你的代码试图创建一个文件,并捕捉抛出的安全异常可能是阻力最小的路径。
Answer 2:
Directory.GetAcessControl(path)
做你所要求的。
public static bool HasWritePermissionOnDir(string path)
{
var writeAllow = false;
var writeDeny = false;
var accessControlList = Directory.GetAccessControl(path);
if (accessControlList == null)
return false;
var accessRules = accessControlList.GetAccessRules(true, true,
typeof(System.Security.Principal.SecurityIdentifier));
if (accessRules ==null)
return false;
foreach (FileSystemAccessRule rule in accessRules)
{
if ((FileSystemRights.Write & rule.FileSystemRights) != FileSystemRights.Write)
continue;
if (rule.AccessControlType == AccessControlType.Allow)
writeAllow = true;
else if (rule.AccessControlType == AccessControlType.Deny)
writeDeny = true;
}
return writeAllow && !writeDeny;
}
(FileSystemRights.Write & rights) == FileSystemRights.Write
是使用所谓的“标志” BTW它,如果你不知道它是什么你应该阅读了关于:)
Answer 3:
Deny
的优先级高于Allow
。 本地规则优先于继承的规则。 我见过很多解决方案(包括这里省略了一些答案),但他们没有考虑到规则是否继承与否。 因此,我建议以下做法,认为规则的继承(整齐地包裹成一个类):
public class CurrentUserSecurity
{
WindowsIdentity _currentUser;
WindowsPrincipal _currentPrincipal;
public CurrentUserSecurity()
{
_currentUser = WindowsIdentity.GetCurrent();
_currentPrincipal = new WindowsPrincipal(_currentUser);
}
public bool HasAccess(DirectoryInfo directory, FileSystemRights right)
{
// Get the collection of authorization rules that apply to the directory.
AuthorizationRuleCollection acl = directory.GetAccessControl()
.GetAccessRules(true, true, typeof(SecurityIdentifier));
return HasFileOrDirectoryAccess(right, acl);
}
public bool HasAccess(FileInfo file, FileSystemRights right)
{
// Get the collection of authorization rules that apply to the file.
AuthorizationRuleCollection acl = file.GetAccessControl()
.GetAccessRules(true, true, typeof(SecurityIdentifier));
return HasFileOrDirectoryAccess(right, acl);
}
private bool HasFileOrDirectoryAccess(FileSystemRights right,
AuthorizationRuleCollection acl)
{
bool allow = false;
bool inheritedAllow = false;
bool inheritedDeny = false;
for (int i = 0; i < acl.Count; i++) {
var currentRule = (FileSystemAccessRule)acl[i];
// If the current rule applies to the current user.
if (_currentUser.User.Equals(currentRule.IdentityReference) ||
_currentPrincipal.IsInRole(
(SecurityIdentifier)currentRule.IdentityReference)) {
if (currentRule.AccessControlType.Equals(AccessControlType.Deny)) {
if ((currentRule.FileSystemRights & right) == right) {
if (currentRule.IsInherited) {
inheritedDeny = true;
} else { // Non inherited "deny" takes overall precedence.
return false;
}
}
} else if (currentRule.AccessControlType
.Equals(AccessControlType.Allow)) {
if ((currentRule.FileSystemRights & right) == right) {
if (currentRule.IsInherited) {
inheritedAllow = true;
} else {
allow = true;
}
}
}
}
}
if (allow) { // Non inherited "allow" takes precedence over inherited rules.
return true;
}
return inheritedAllow && !inheritedDeny;
}
}
但是,我做了经验,这并不总是在远程计算机上工作,你不会总是要查询有该文件的访问权限的权利。 在这种情况下的解决方法是尝试; 可能甚至是只是想创建一个临时文件,如果您需要正确的“真实”的文件工作前需要了解的访问。
Answer 4:
接受答案由千电子伏到这个问题实际上并不给任何代码,它只是指出,我不能够访问其他资源。 因此,这里的在功能我最好的尝试。 实际上,它会检查它看权限是“写”权限和当前用户属于相应的组。
它可能是不完整的关于网络路径或什么,但它不够好,我的目的,检查下“程序文件”本地配置文件的可写性:
using System.Security.Principal;
using System.Security.AccessControl;
private static bool HasWritePermission(string FilePath)
{
try
{
FileSystemSecurity security;
if (File.Exists(FilePath))
{
security = File.GetAccessControl(FilePath);
}
else
{
security = Directory.GetAccessControl(Path.GetDirectoryName(FilePath));
}
var rules = security.GetAccessRules(true, true, typeof(NTAccount));
var currentuser = new WindowsPrincipal(WindowsIdentity.GetCurrent());
bool result = false;
foreach (FileSystemAccessRule rule in rules)
{
if (0 == (rule.FileSystemRights &
(FileSystemRights.WriteData | FileSystemRights.Write)))
{
continue;
}
if (rule.IdentityReference.Value.StartsWith("S-1-"))
{
var sid = new SecurityIdentifier(rule.IdentityReference.Value);
if (!currentuser.IsInRole(sid))
{
continue;
}
}
else
{
if (!currentuser.IsInRole(rule.IdentityReference.Value))
{
continue;
}
}
if (rule.AccessControlType == AccessControlType.Deny)
return false;
if (rule.AccessControlType == AccessControlType.Allow)
result = true;
}
return result;
}
catch
{
return false;
}
}
Answer 5:
海事组织,你需要这样的目录照常上班,但不是在使用前检查权限,提供正确的方式来处理UnauthorizedAccessException并做出相应的反应。 这种方法更容易,更容易出错。
Answer 6:
尝试使用本C#代码片段我刚刚制作的工作:
using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string directory = @"C:\downloads";
DirectoryInfo di = new DirectoryInfo(directory);
DirectorySecurity ds = di.GetAccessControl();
foreach (AccessRule rule in ds.GetAccessRules(true, true, typeof(NTAccount)))
{
Console.WriteLine("Identity = {0}; Access = {1}",
rule.IdentityReference.Value, rule.AccessControlType);
}
}
}
}
而这里的一个参考,你也可以关注一下。 我的代码可能会给你的想法,你怎么能试图写入到一个目录之前检查的权限。
Answer 7:
根据此链接: http://www.authorcode.com/how-to-check-file-permission-to-write-in-c/
它更容易使用现有的类安全管理器
string FileLocation = @"C:\test.txt";
FileIOPermission writePermission = new FileIOPermission(FileIOPermissionAccess.Write, FileLocation);
if (SecurityManager.IsGranted(writePermission))
{
// you have permission
}
else
{
// permission is required!
}
但似乎它已经过时,建议使用的PermissionSet来代替。
[Obsolete("IsGranted is obsolete and will be removed in a future release of the .NET Framework. Please use the PermissionSet property of either AppDomain or Assembly instead.")]
Answer 8:
private static void GrantAccess(string file)
{
bool exists = System.IO.Directory.Exists(file);
if (!exists)
{
DirectoryInfo di = System.IO.Directory.CreateDirectory(file);
Console.WriteLine("The Folder is created Sucessfully");
}
else
{
Console.WriteLine("The Folder already exists");
}
DirectoryInfo dInfo = new DirectoryInfo(file);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
dInfo.SetAccessControl(dSecurity);
}
文章来源: Checking for directory and file write permissions in .NET