控制 NTFS 目錄存取權限 (ACL) 是檔案伺服器、多使用者應用、安全性合規常見需求。本文完整示範 C# 使用 `System.Security.AccessControl` 新增、移除、讀取、稽核目錄權限,含繼承旗標、傳播旗標、存取規則類型完整解析。
using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
public static class DirectoryAclManager
{
///
/// 為目錄新增使用者/群組存取權限
///
/// 目標目錄完整路徑
/// 使用者/群組名稱 (如 "Users", "DOMAIN\\User", "Everyone")
/// 權限字串: R=Read, W=Write, M=Modify, F=FullControl, C=ChangePermissions
/// 繼承模式
/// Allow/Deny
public static void AddDirectoryAccessRule(
string directoryPath,
string identity,
string rights,
InheritanceFlags inheritance = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
AccessControlType accessType = AccessControlType.Allow)
{
if (!Directory.Exists(directoryPath))
throw new DirectoryNotFoundException($"目錄不存在:{directoryPath}");
// 解析權限字串
FileSystemRights fsRights = ParseRights(rights);
// 取得現有安全性描述元
DirectoryInfo dirInfo = new DirectoryInfo(directoryPath);
DirectorySecurity dirSecurity = dirInfo.GetAccessControl(AccessControlSections.Access);
// 建立存取規則
var rule = new FileSystemAccessRule(
identity,
fsRights,
inheritance,
PropagationFlags.None,
accessType);
// 新增規則 (不覆蓋既有)
dirSecurity.AddAccessRule(rule);
// 套用變更
dirInfo.SetAccessControl(dirSecurity);
}
private static FileSystemRights ParseRights(string rights)
{
FileSystemRights result = 0;
foreach (char c in rights.ToUpper())
{
result |= c switch
{
'R' => FileSystemRights.Read,
'W' => FileSystemRights.Write,
'M' => FileSystemRights.Modify,
'F' => FileSystemRights.FullControl,
'C' => FileSystemRights.ChangePermissions,
'T' => FileSystemRights.TakeOwnership,
'D' => FileSystemRights.Delete,
'A' => FileSystemRights.AppendData,
_ => 0
};
}
return result;
}
}
public static void ListDirectoryPermissions(string directoryPath)
{
if (!Directory.Exists(directoryPath))
{
Console.WriteLine("目錄不存在");
return;
}
DirectorySecurity security = Directory.GetAccessControl(directoryPath, AccessControlSections.All);
Console.WriteLine($"=== {directoryPath} 權限列表 ===");
Console.WriteLine($"擁有者:{security.GetOwner(typeof(NTAccount))}");
Console.WriteLine($"群組:{security.GetGroup(typeof(NTAccount))}");
// DACL (存取規則)
var accessRules = security.GetAccessRules(true, true, typeof(NTAccount));
Console.WriteLine("\n--- 存取規則 (DACL) ---");
foreach (FileSystemAccessRule rule in accessRules)
{
Console.WriteLine($"身分:{rule.IdentityReference.Value,-30} " +
$"類型:{rule.AccessControlType,-5} " +
$"權限:{rule.FileSystemRights,-20} " +
$"繼承:{rule.InheritanceFlags,-25} " +
$"傳播:{rule.PropagationFlags} " +
$"{(rule.IsInherited ? "[繼承]" : "[明確]")}");
}
// SACL (稽核規則)
var auditRules = security.GetAuditRules(true, true, typeof(NTAccount));
Console.WriteLine("\n--- 稽核規則 (SACL) ---");
foreach (FileSystemAuditRule rule in auditRules)
{
Console.WriteLine($"身分:{rule.IdentityReference.Value,-30} " +
$"類型:{rule.AuditFlags,-15} " +
$"繼承:{rule.InheritanceFlags} " +
$"{(rule.IsInherited ? "[繼承]" : "[明確]")}");
}
}
public static void RemoveDirectoryAccessRule(
string directoryPath,
string identity,
FileSystemRights rights,
InheritanceFlags inheritance,
AccessControlType accessType)
{
DirectoryInfo dirInfo = new DirectoryInfo(directoryPath);
DirectorySecurity dirSecurity = dirInfo.GetAccessControl(AccessControlSections.Access);
var rule = new FileSystemAccessRule(identity, rights, inheritance, PropagationFlags.None, accessType);
// 移除完全匹配的規則
bool removed = dirSecurity.RemoveAccessRule(rule);
// 或移除所有匹配身分的規則
// bool removed = dirSecurity.PurgeAccessRules(new NTAccount(identity));
if (removed)
{
dirInfo.SetAccessControl(dirSecurity);
Console.WriteLine("規則已移除");
}
else
{
Console.WriteLine("找不到匹配的規則");
}
}
public static void AddRuleBySid(string directoryPath, string sidString, FileSystemRights rights)
{
var sid = new SecurityIdentifier(sidString);
var rule = new FileSystemAccessRule(sid, rights,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None, AccessControlType.Allow);
var dirInfo = new DirectoryInfo(directoryPath);
var security = dirInfo.GetAccessControl(AccessControlSections.Access);
security.AddAccessRule(rule);
dirInfo.SetAccessControl(security);
}
// 知名 SID
var everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); // S-1-1-0
var administratorsSid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null); // S-1-5-32-544
var usersSid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null); // S-1-5-32-545
// 1. 給 Users 群組讀寫權限 (繼承至子項)
DirectoryAclManager.AddDirectoryAccessRule(@"D:\SharedData", "Users", "RW");
// 2. 給 Administrators 完全控制
DirectoryAclManager.AddDirectoryAccessRule(@"D:\SharedData", "Administrators", "F");
// 3. 列出權限
DirectoryAclManager.ListDirectoryPermissions(@"D:\SharedData");
// 4. 移除特定規則
DirectoryAclManager.RemoveDirectoryAccessRule(
@"D:\SharedData", "Guest", FileSystemRights.FullControl,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
AccessControlType.Allow);
掌握 ACL 程式化操作,能建立自動化部署腳本、權限管理工具、合規稽核系統,確保檔案系統安全性策略精確落地。