【问题标题】:How to modify file access control in .NET Core如何在 .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 上做了什么(如果已经完成)。

标签: c# file-permissions .net-core


【解决方案1】:

FileSecurity 类现在是 .NET Core 的 System.IO.FileSystem.AccessControl 包的一部分。不再有 File.GetAccessControl 方法,因此您需要自己实例化 FileSecurity 实例。

【讨论】:

  • 顺便说一句,创建新的 .NET Core 2.0 库将不包含此程序集。您必须将 System.IO.FileSystem.AccessControl 添加为 NuGet 包。
  • @Scyssion 是的,我的评论是这样说的。
  • 举个例子会有很大帮助。我在任何地方都找不到 .net 核心的工作示例。
  • 请注意,与 .NET Core API 不同,该包不支持长文件名。有关详细信息,请在下面查看我的其他答案。
【解决方案2】:

此时有两种扩展方式:GetAccessControlSetAccessControl,用于FileInfoDirectoryInfo

所以你可以使用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.奖金

如何获得groupothers,或者...我对等价物的定义?

var group = security.GetGroup(typeof(NTAccount));

var others = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)
                 .Translate(typeof(NTAccount));

注意:此代码来自我的开源项目Lx.Shell

【讨论】:

  • 这打击......他们为什么要让它变得如此复杂?为什么没有 DirectoryInfo 和 FileInfo 上的一些扩展方法?
  • 您的代码中的“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 中的 GetAccessControlSetAccessControl 与其他 .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。项目。谢谢
      猜你喜欢
      • 2021-05-12
      • 2016-07-29
      • 2016-01-31
      • 1970-01-01
      • 2017-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-26
      相关资源
      最近更新 更多