如何在 .NET Core 中修改文件访问控制
Posted
技术标签:
【中文标题】如何在 .NET Core 中修改文件访问控制【英文标题】:How to modify file access control in .NET Core 【发布时间】:2017-03-19 21:34:30 【问题描述】:我正在尝试更改 .NET Core 中文件的权限。
但是,FileInfo 似乎不再有任何SetAccessControl
。
// Create a new FileInfo object.
FileInfo fInfo = new FileInfo(FileName);
// Get a FileSecurity object that represents the
// current security settings.
FileSecurity fSecurity = fInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
fSecurity.AddAccessRule(new FileSystemAccessRule(Account,
Rights,
ControlType));
// Set the new access settings.
fInfo.SetAccessControl(fSecurity);
目标只是为文件的当前所有者添加执行权(这不是 Windows 或 Unix 特定的功能)。
关于如何在 .NET Core 上执行此操作的任何线索?
【问题讨论】:
您希望在具有不同访问控制系统的 Unix 上发生什么?还是这是一个仅限 Windows 的 .Net Core 应用程序? @svick 我希望有一个共同的子集。我会检查 Mono 上做了什么(如果已经完成)。 【参考方案1】:FileSecurity
类现在是 .NET Core 的 System.IO.FileSystem.AccessControl 包的一部分。不再有 File.GetAccessControl
方法,因此您需要自己实例化 FileSecurity
实例。
【讨论】:
顺便说一句,创建新的 .NET Core 2.0 库将不包含此程序集。您必须将System.IO.FileSystem.AccessControl
添加为 NuGet 包。
@Scyssion 是的,我的评论是这样说的。
举个例子会有很大帮助。我在任何地方都找不到 .net 核心的工作示例。
@Learner 查看unit tests project in the Github repository 示例
请注意,与 .NET Core API 不同,该包不支持长文件名。有关详细信息,请在下面查看我的其他答案。【参考方案2】:
此时有两种扩展方式:GetAccessControl
和SetAccessControl
,用于FileInfo
、DirectoryInfo
等
所以你可以使用var ac = new FileInfo(path).GetAccessControl()
,这个表达式在 .NET Framework 和 .Net Core 中都有效。但是你仍然需要dotnet add package System.IO.FileSystem.AccessControl
。
File.GetAccessControl
在 .NET Core 中不可用。
参考:https://docs.microsoft.com/dotnet/api/system.io.filesystemaclextensions.getaccesscontrol
【讨论】:
应该是公认的答案,这样更容易使用【参考方案3】:如何在 Windows 上获取和修改用户组其他权限
我终于实现了Windows文件权限访问:
1.获取文件安全性:
var security = new FileSecurity(fileSystemInfoFullName,
AccessControlSections.Owner |
AccessControlSections.Group |
AccessControlSections.Access);
2。获取授权规则:
var authorizationRules = security.GetAccessRules(true, true, typeof(NTAccount));
3.获取所有者的授权规则:
var owner = security.GetOwner(typeof(NTAccount));
foreach (AuthorizationRule rule in authorizationRules)
FileSystemAccessRule fileRule = rule as FileSystemAccessRule;
if (fileRule != null)
if (owner != null && fileRule.IdentityReference == owner)
if (fileRule.FileSystemRights.HasFlag(FileSystemRights.ExecuteFile) ||
fileRule.FileSystemRights.HasFlag(FileSystemRights.ReadAndExecute) ||
fileRule.FileSystemRights.HasFlag(FileSystemRights.FullControl))
ownerRights.IsExecutable = true;
else if (group != null && fileRule.IdentityReference == group)
// TO BE CONTINUED...
4.为所有者添加规则:
security.ModifyAccessRule(AccessControlModification.Add,
new FileSystemAccessRule(owner, FileSystemRights.Modify, AccessControlType.Allow),
out bool modified);
5.奖金
如何获得group
和others
,或者...我对等价物的定义?
var group = security.GetGroup(typeof(NTAccount));
var others = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)
.Translate(typeof(NTAccount));
注意:此代码来自我的开源项目Lx.Shell
【讨论】:
这打击......他们为什么要让它变得如此复杂?为什么没有 DirectoryInfo 和 FileInfo 上的一些扩展方法? 这适用于 UNIX:***.com/questions/45132081/… 您的代码中的“ownerRights”和“group”是什么?【参考方案4】:文档说这是受支持的并且它有效(对我来说)。 https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemaclextensions?view=dotnet-plat-ext-3.1 有一个 SetAccessControl 方法
请务必添加System.IO.FileSystem.AccessControl
NuGet 包。
这是我在 .NET Framework 中的内容:
var ds = new DirectorySecurity();
ds.AddAccessRule(new FileSystemAccessRule(adminSI, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
ds.SetAccessRuleProtection(true, false); // disable inheritance and clear any inherited permissions
Directory.SetAccessControl(<path to directory>, ds);
这就是它在 .NET Core 3.1 中的作用。只有最后一行不同:
var ds = new DirectorySecurity();
ds.AddAccessRule(new FileSystemAccessRule(adminSI, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
ds.SetAccessRuleProtection(true, false); // disable inheritance and clear any inherited permissions
System.IO.FileSystemAclExtensions.SetAccessControl(new DirectoryInfo(<path to directory>), ds);
【讨论】:
【参考方案5】:这是为了补充其他答案。请注意,System.IO.FileSystem.AccessControl
中的 GetAccessControl
和 SetAccessControl
与其他 .NET Core System.IO
API 一样不支持长文件名(255 个字符)。
你收到的异常是内部调用抛出的ArgumentException
,参数是name
。
如果你使用的是那个包,如果你发现长文件名,你需要添加这个:
if (usingFile.FullName.Length > 255)
usingFile = new FileInfo(@"\\?\" + file.FullName);
或
if (folder.FullName.Length > 255)
folder = new DirectoryInfo(@"\\?\" + folder.FullName);
【讨论】:
【参考方案6】:另一种处理目录或文件的acls的方法:
// Adds an ACL entry on the specified directory for the specified account.
public static void AddDirectorySecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType)
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(FileName);
// Get a DirectorySecurity object that represents the
// current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(Account,
Rights,
ControlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
// Removes an ACL entry on the specified directory for the specified account.
public static void RemoveDirectorySecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType)
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(FileName);
// Get a DirectorySecurity object that represents the
// current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.RemoveAccessRule(new FileSystemAccessRule(Account,
Rights,
ControlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
// Adds an ACL entry on the specified file for the specified account.
public static void AddFileSecurity(string fileName, string account,
FileSystemRights rights, AccessControlType controlType)
// Create a new FileInfo object.
FileInfo fInfo = new FileInfo(fileName);
// Get a FileSecurity object that represents the
// current security settings.
FileSecurity fSecurity = fInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
fSecurity.AddAccessRule(new FileSystemAccessRule(account,
rights, controlType));
// Set the new access settings.
fInfo.SetAccessControl(fSecurity);
// Removes an ACL entry on the specified file for the specified account.
public static void RemoveFileSecurity(string fileName, string account,
FileSystemRights rights, AccessControlType controlType)
// Create a new FileInfo object.
FileInfo fInfo = new FileInfo(fileName);
// Get a FileSecurity object that represents the
// current security settings.
FileSecurity fSecurity = fInfo.GetAccessControl();
// Remove the FileSystemAccessRule from the security settings.
fSecurity.RemoveAccessRule(new FileSystemAccessRule(account,
rights, controlType));
// Set the new access settings.
fInfo.SetAccessControl(fSecurity);
//example for open onClick folderdialog and get owner by NTACCOUNT of folder from acl
private async void Button_Click(object sender, RoutedEventArgs e)
var folderPicker = new Windows.Storage.Pickers.FolderPicker();
folderPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
folderPicker.FileTypeFilter.Add("*");
Windows.Storage.StorageFolder folder = await folderPicker.PickSingleFolderAsync();
if (folder != null)
// Application now has read/write access to all contents in the picked folder
// (including other sub-folder contents)
Windows.Storage.AccessCache.StorageApplicationPermissions.
FutureAccessList.AddOrReplace("PickedFolderToken", folder);
// Create a new FileInfo object.
FileInfo fInfo = new FileInfo(folder.ToString());
// Get a FileSecurity object that represents the
// current security settings.
FileSecurity fSecurity = fInfo.GetAccessControl();
IdentityReference identityReference = fSecurity.GetOwner(typeof(SecurityIdentifier));
NTAccount ntAccount = identityReference.Translate(typeof(NTAccount)) as NTAccount;
var fileOwner = ntAccount.Value;
//do something with file Owner
//this.tb1.Text = "folder: " + folder.Name + " in Pfad: " + folder.Path + "owned by: " + fileOwner;
else
//error Handler
【讨论】:
正如原来的问题所说...... Net Core 不再有 GetAccessControl 或 SetAccessControl 方法在 DirectoryInfo 上 GetAccessControl 和 SetAccessControl 已完全从 Net Core 3.0 及更高版本中撤出,但它可以在 2.2 中使用。如果你试图运行它,你会得到一个 Method Not Found 异常(或类似的东西)。我有一个正是这个问题的多目标项目,它适用于 Framework 4.7.2 和 Core 2.2,但在 Core 3.0 和 3.1 上失败。 然后它来自 2.2。项目。谢谢以上是关于如何在 .NET Core 中修改文件访问控制的主要内容,如果未能解决你的问题,请参考以下文章
如何让asp.net core mvc发布时候不编译cshtml视图