簡體   English   中英

.NET Core中如何修改文件訪問控制

[英]How to modify file access control in .NET Core

我正在嘗試更改 .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 上執行此操作的任何線索?

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

如何在 Windows 上獲取和修改用戶組其他權限

我終於實現了Windows文件權限訪問:

1.獲取文件安全:

      var security = new FileSecurity(fileSystemInfoFullName, 
                AccessControlSections.Owner | 
                AccessControlSections.Group |
                AccessControlSections.Access);

2、獲取授權規則:

var authorizationRules = security.GetAccessRules(true, true, typeof(NTAccount));

3.獲取owner的授權規則:

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

此時有兩種擴展方法: 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

文檔說這是支持的並且它有效(對我來說)。 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);

這是添加到其他答案。 請注意, GetAccessControlSetAccessControlSystem.IO.FileSystem.AccessControl支持長文件名(255個字符)像其他.NET核心System.IO的API。

您收到的異常是內部調用拋出的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 的略有不同,所以我想將它包含在其他人手中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM