【问题标题】:How to set "modify" ACL on a Windows file using Java如何使用 Java 在 Windows 文件上设置“修改”ACL
【发布时间】:2023-04-09 21:24:01
【问题描述】:

如何使用 Java 7 的文件 API 设置 Windows ACL,以便模拟添加用户/组和以下选项:

例如,在操作系统属性对话框中,您可以选择以下内容进行基本写访问:

  • 修改
  • ☑ 读取并执行(自动选择)
  • ☑ 列出文件夹内容(自动选择)
  • ☑ 阅读(自动选择)
  • ☑ 写入(自动选择)

但是,当我使用 Java 7 的 File API 使用类似选项时,它会选择:

  • ☑ 特别
    • ☑ 高级(不编辑,点击用户或组,查看)
      • 显示高级权限
      • 高级权限
        • ☑(一堆复选框)

这不仅更难管理(遍历对话框更容易遗漏某些内容),而且与单击这些框的行为不同。一些 UAC 提示的行为不同。更糟糕的是,由于对话遍历,切换权限(例如从 Windows 桌面)变得更加困难,从而增加了出错的机会。

如何使用 Java 设置这些复选框?

UserPrincipal authenticatedUsers = path.getFileSystem().getUserPrincipalLookupService()
        .lookupPrincipalByName("Authenticated Users");
AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);

// Create ACL to give "Authenticated Users" "modify" access
AclEntry entry = AclEntry.newBuilder()
        .setType(AclEntryType.ALLOW)
        .setPrincipal(authenticatedUsers)
        .setPermissions(DELETE, DELETE_CHILD, LIST_DIRECTORY, READ_DATA, READ_ATTRIBUTES, ADD_FILE, WRITE_DATA, WRITE_ATTRIBUTES)
        .build();

List<AclEntry> acl = view.getAcl();
acl.add(0, entry); // insert before any DENY entries
view.setAcl(acl);

【问题讨论】:

    标签: java windows file permissions acl


    【解决方案1】:

    我能够通过创建一个我想模仿的文件夹来模仿 Windows 属性文件权限,通过属性对话框设置值,然后将它们回显出来......

    // Echo ACL
    Path path = Paths.get("C:\\myfolder");
    
    UserPrincipal authenticatedUsers = path.getFileSystem().getUserPrincipalLookupService()
            .lookupPrincipalByName("Authenticated Users");
    
    AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
    for(AclEntry entry : view.getAcl()) {
        if(entry.principal().equals(authenticatedUsers)) {
            System.out.println("=== flags ===");
            for (AclEntryFlag flags : entry.flags()) {
                System.out.println(flags.name());
            }
    
            System.out.println("=== permissions ===");
            for (AclEntryPermission permission : entry.permissions()) {
                System.out.println(permission.name());
            }
        }
    }
    

    输出:

    === flags ===
    DIRECTORY_INHERIT
    FILE_INHERIT
    
    === permissions ===
    WRITE_NAMED_ATTRS
    WRITE_ATTRIBUTES
    DELETE
    WRITE_DATA
    READ_ACL
    APPEND_DATA
    READ_ATTRIBUTES
    READ_DATA
    EXECUTE
    SYNCHRONIZE
    READ_NAMED_ATTRS
    

    然后,我能够将这些值插入到我原来的示例中:

    UserPrincipal authenticatedUsers = path.getFileSystem().getUserPrincipalLookupService()
            .lookupPrincipalByName("Authenticated Users");
    AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
    
    // Create ACL to give "Authenticated Users" "modify" access
    AclEntry entry = AclEntry.newBuilder()
            .setType(AclEntryType.ALLOW)
            .setPrincipal(authenticatedUsers)
            .setFlags(DIRECTORY_INHERIT,
                      FILE_INHERIT)
            .setPermissions(WRITE_NAMED_ATTRS,
                            WRITE_ATTRIBUTES,
                            DELETE,
                            WRITE_DATA,
                            READ_ACL,
                            APPEND_DATA,
                            READ_ATTRIBUTES,
                            READ_DATA,
                            EXECUTE,
                            SYNCHRONIZE,
                            READ_NAMED_ATTRS)
            .build();
    

    ...现在“修改”已完全按照需要进行检查。

    【讨论】:

    • 仅供参考,如果您的代码需要以不同的语言运行,lookupPrincipalByName("Authenticated Users") 将不起作用,因为例如在法国机器上该组称为:“utilisateurs authentifiés”。该组“S-1-5-11”有一个独立于语言的 SID,您可以在此处找到:docs.microsoft.com/en-us/windows/security/identity-protection/… 但是,无法使用具有该 SID 的 Java API 来获取 UserPrincipal。我必须编写本机 C++ 代码才能完成这项工作。
    • @ThomasIbbotson 如果您最终开发了一种使用 JNA 执行此操作的方法,请分享。 JNA 团队非常乐于接受 API 添加,尤其是那些修复此类重大问题的 API。
    猜你喜欢
    • 2016-01-11
    • 2014-02-26
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 2022-01-05
    • 1970-01-01
    相关资源
    最近更新 更多