如何在.net Core中修改文件访问控制

本文关键字:修改 文件 访问控制 Core net | 更新日期: 2023-09-27 18:16:36

我试图改变。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上做到这一点有什么线索吗?

如何在.net Core中修改文件访问控制

FileSecurity类现在是。net Core的system . io . filessystem . accesscontrol包的一部分。不再有File.GetAccessControl方法,所以您需要自己实例化FileSecurity实例。

此时有两个扩展方法:GetAccessControlSetAccessControl,用于FileInfo, DirectoryInfo等。

所以你可以使用var ac = new FileInfo(path).GetAccessControl(),这个表达式在。net Framework和。net Core中都是有效的。但是你仍然需要dotnet add package System.IO.FileSystem.AccessControl

File.GetAccessControl在。net Core中不可用。

裁判:https://learn.microsoft.com/dotnet/api/system.io.filesystemaclextensions.getaccesscontrol

如何获取和修改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。为owner添加规则:

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。壳牌

文档说这是支持的,它工作(对我来说)。https://learn.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);

这是为了添加到其他答案中。请注意,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);
}

另一种处理目录或文件acl的方法:

       // 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
        }
    }

按照@jon-r所说的,我能够让我的工作。这在。net 7中仍然适用。这是使用System.IO.FileSystem.AccessControlSystem.IO NuGet包。

我的。net Framework 4.8代码:
var ds = Directory.GetAccessControl(dir);
ds.AddAccessRule(new FileSystemAccessRule(user, FileSystemRights.Modify, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));
ds.AddAccessRule(new FileSystemAccessRule(user, FileSystemRights.Modify, InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
Directory.SetAccessControl(dir, ds);
我的。net 7代码:
var ds = new DirectorySecurity();
ds.AddAccessRule(new FileSystemAccessRule(user, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
System.IO.FileSystemAclExtensions.SetAccessControl(new DirectoryInfo(dir), ds);

我最初的代码看起来和Jon的有点不同,所以我想把它包含在其他人的代码中。