C# 中目录的读取权限

发布于 2024-08-21 23:00:30 字数 2612 浏览 3 评论 0原文

我注意到,如果更改特定目录的安全设置,则可以使该文件夹在 Windows 中不再“可浏览”。特别是,将管理员的“读取”权限更改为“拒绝”将使该文件夹无法访问。

我现在的问题是,如何在代码中解决这个问题?我的跟随让我接近,但它仍然不对:

/// <summary>
/// Takes in a directory and determines if the current user has read access to it (doesn't work for network drives)
/// THIS IS VERY HACKY
/// </summary>
/// <param name="dInfo">directoryInfo object to the directory to examine</param>
/// <returns>true if read access is available, false otherwise</returns>
public static bool IsDirectoryReadable(DirectoryInfo dInfo)
{
    try
    {
        System.Security.AccessControl.DirectorySecurity dirSec = dInfo.GetAccessControl();
        System.Security.Principal.WindowsIdentity self = System.Security.Principal.WindowsIdentity.GetCurrent();
        System.Security.Principal.WindowsPrincipal selfGroup = new System.Security.Principal.WindowsPrincipal(self);
        // Go through each access rule found for the directory
        foreach (System.Security.AccessControl.FileSystemAccessRule ar in dirSec.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier)))
        {
            if (selfGroup.IsInRole((System.Security.Principal.SecurityIdentifier)ar.IdentityReference))
            {
                // See if the Read right is included
                if ((ar.FileSystemRights & System.Security.AccessControl.FileSystemRights.Read) == System.Security.AccessControl.FileSystemRights.Read)
                {
                    if (ar.AccessControlType == System.Security.AccessControl.AccessControlType.Allow)
                    {
                        // If all of the above are true, we do have read access to this directory
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
        }
        // If we didn't find anything
        return false;
    }
    catch
    {
        // If anything goes wrong, assume false
        return false;
    }
}

我与上面的接近,但我仍然错过了一些巨大的东西。如果我右键单击文件夹来设置权限,我会看到(在我的示例中)3 个组或用户名:“Administrators、myUserName 和 SYSTEM”。如果我将“管理员”或“myUserName”的“读取”设置为“拒绝”,我将无法再浏览该目录。如果我只将“系统”设置为“拒绝”,我仍然可以浏览它。

似乎隐含某种权限层次结构,其中 myUserName 或 Administrator 取代 SYSTEM 组/用户。

上面的代码查找它为我的用户身份找到的第一个允许“读取”并返回 true。我还可以编写代码来查找 Read 的第一个“Deny”并返回 false。

我可以将一个文件夹设置为“系统”的“读取”-“拒绝”,以及其他两个帐户的“读取”-“允许”,并且仍然读取该文件夹。如果我更改代码来查找 Deny,并且它首先遇到 SYSTEM 用户身份,我的函数将返回“false”,这是... false。对于其他两个帐户,很可能是“读取”-“允许”。

我仍然无法弄清楚的问题是,如何确定哪个用户身份权限优先于所有其他用户身份权限?

I've noticed if you change the security settings for a particular directory, you can make that folder no longer "browsable" in windows. In particular, changing the "Read" permission for Administrators to "Deny" will make that folder inaccessible.

The question I now have, is how do I figure this out in code? I following gets me close, but it still ain't right:

/// <summary>
/// Takes in a directory and determines if the current user has read access to it (doesn't work for network drives)
/// THIS IS VERY HACKY
/// </summary>
/// <param name="dInfo">directoryInfo object to the directory to examine</param>
/// <returns>true if read access is available, false otherwise</returns>
public static bool IsDirectoryReadable(DirectoryInfo dInfo)
{
    try
    {
        System.Security.AccessControl.DirectorySecurity dirSec = dInfo.GetAccessControl();
        System.Security.Principal.WindowsIdentity self = System.Security.Principal.WindowsIdentity.GetCurrent();
        System.Security.Principal.WindowsPrincipal selfGroup = new System.Security.Principal.WindowsPrincipal(self);
        // Go through each access rule found for the directory
        foreach (System.Security.AccessControl.FileSystemAccessRule ar in dirSec.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier)))
        {
            if (selfGroup.IsInRole((System.Security.Principal.SecurityIdentifier)ar.IdentityReference))
            {
                // See if the Read right is included
                if ((ar.FileSystemRights & System.Security.AccessControl.FileSystemRights.Read) == System.Security.AccessControl.FileSystemRights.Read)
                {
                    if (ar.AccessControlType == System.Security.AccessControl.AccessControlType.Allow)
                    {
                        // If all of the above are true, we do have read access to this directory
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
        }
        // If we didn't find anything
        return false;
    }
    catch
    {
        // If anything goes wrong, assume false
        return false;
    }
}

I'm close with the above, but I'm still missing something huge. If I right click on a folder to set permissions, I see (in my example) 3 groups or user names: "Administrators, myUserName and SYSTEM". If I set the "Read" to Deny for either "Administrators" or "myUserName" I can no longer browse the directory. If I only set "System" to "Deny", I can still browse it.

There seems to be some sort of permission hierarchy implied, where either myUserName or Administrator supersedes the SYSTEM group/user.

The code above looks for the first Allow for "Read" it finds for my user identity and returns true. I could also write code that looks for the first "Deny" for Read and returns false.

I can set a folder to be Read - "Deny" for SYSTEM and Read - "Allow" for the other two accounts and still read the folder. If I change the code to look for Deny's and it encounters the SYSTEM user identity first, my function will return "false", which is... false. It might very well be Read - "Allow" for the other two accounts.

The problem that I still can't figure out is, how can I determine which user identity permission has priority over all of the others?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绾颜 2024-08-28 23:00:30

这变得非常棘手,因为 ACL 允许继承,但它们也有一个最严格的访问限制模型。换句话说,如果您在用户链中的任何位置对资源进行了拒绝,那么无论有多少其他组可能会给您允许,您都会被拒绝。 MSDN 上有一篇关于该主题的好文章

It gets very tricky because ACL's allow inheritance, but they also have a model of most restrictive access. In other words, if you have a DENY anywhere in your user chain to a resource, no matter how many other groups may give you an ALLOW, you are denied. There is a good article on the subect on MSDN.

忆梦 2024-08-28 23:00:30

系统组与操作系统进程相关,与您的用户帐户没有直接关系。如果没有用户上下文,操作系统将使用它来访问文件系统。由于您的应用程序作为您的“用户名”运行,因此权限来自它及其所在的组。在这种情况下,不要认为您需要检查系统,除非我遗漏了某些内容。

更新:请记住Directory.Exists() 还将检查您是否有权读取该目录。

The system group is related to the O/S process and not directly related to your user account. It's what the O/S would use to access the filesystem if there was no user context. Since your application is running as your "username" the permissions come from it and the groups it's in. Don't think you need to be checking System in this case unless I'm missing something.

Update: Keep in mind that Directory.Exists() will also check that you have permissions to read the directory.

ゞ花落谁相伴 2024-08-28 23:00:30

问题不在于权限层次结构。问题是您的代码根据第一个匹配的角色返回 true 或 false。您确实需要评估所有权限。

我最近不得不处理这个问题...我发布了我的代码 这里

The issue isn’t a permission hierarchy. The problem is that your code is returning true or false based on the first matching Role. You really need to evaluate all permissions.

I recently had to deal with this issue... I posted my code here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文