有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在子文件夹上使用java设置ACL的文件权限失败(缺少继承)

以下代码为组G-Test设置文件夹“\\myShare\Folder1\”的“读取”权限:

String gName="G-Test";
AclEntryPermission[] aeps=new AclEntryPermission[]{
        AclEntryPermission.READ_DATA,
        AclEntryPermission.READ_ATTRIBUTES,
        AclEntryPermission.READ_NAMED_ATTRS,
        AclEntryPermission.READ_ACL,
        AclEntryPermission.SYNCHRONIZE
    };      
Path p = FileSystems.getDefault().getPath(new File("\\\\myShare\\Folder1\\").getPath());
AclFileAttributeView view = Files.getFileAttributeView(p, AclFileAttributeView.class);
Set<AclEntryPermission> set = EnumSet.noneOf(AclEntryPermission.class);
for (AclEntryPermission acp: aeps) set.add(acp);
AclEntry.Builder b= AclEntry.newBuilder();
b.setType(AclEntryType.ALLOW);
b.setPermissions(set);
b.setPrincipal(FileSystems.getDefault().getUserPrincipalLookupService().lookupPrincipalByName(gName));
b.setFlags(new AclEntryFlag[]{AclEntryFlag.FILE_INHERIT,AclEntryFlag.DIRECTORY_INHERIT});       
List<AclEntry> acl = view.getAcl();
acl.add(b.build());
view.setAcl(acl);

正如预期的那样,这适用于folder1。但在Folder2(子文件夹:\\myShare\Folder1\Folder2)上,ACL不会被继承。使用Windows GUI查看时,Folder2中缺少继承的ACL

在Folder1中使用Windows更改另一个组/权限的ACL时,我可以看到folder2上以前缺少的权限。或者在创建新的子文件夹时,ACL被正确继承

上面的代码有问题吗?我想设置对所有子文件夹和文件继承的文件夹1的读取权限

该代码在Windows8.1 PC上运行,共享的是Windows2008R2文件集群


共 (1) 个答案

  1. # 1 楼答案

    您的代码运行良好。我有一个几乎相同的结构来设置我的环境中的权限,它也在那里工作。问题是修改权限时Folder2已经存在。一些Windows API调用会将更改向下传播到目录树,而一些则不会(请参阅this question的答案)。JRE必须使用其中一个不使用的JRE。我想,你必须自己在树上行走才能传播这些变化。但是,如果在设置权限后创建Folder2,则它将具有从顶部继承的权限(至少在我的上是这样)

    编辑: 我进一步思考了这个问题,并认为我将来可能也需要在树上行走。因为我们在这里讨论的是Java7,所以我寻找了一种比过去更简单的方法来遍历树。结果是这些文件。walkFileTree()方法就是一张票!我想到了这个,尽管我愿意分享:

    private void grantAccess(final UserPrincipal user, Path folder) {
        try {
            Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {              
                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    grant(dir);
                    return FileVisitResult.CONTINUE;
                }
    
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    grant(file);
                    return FileVisitResult.CONTINUE;
                }
    
                private void grant(Path p) throws IOException {
                    AclFileAttributeView view = Files.getFileAttributeView(p, AclFileAttributeView.class);
                    AclEntry accessEntry = createAccessACLEntry(user);
                    List<AclEntry> acl = view.getAcl();
                    acl.add(0, accessEntry); // insert at head in case there are any DENY entries
                    view.setAcl(acl);
                }
    
                private AclEntry createAccessACLEntry(UserPrincipal user) {
                    AclEntry entry = AclEntry
                            .newBuilder()
                            .setType(AclEntryType.ALLOW)
                            .setPrincipal(user)
                            .setPermissions(AclEntryPermission.DELETE_CHILD,
                                    AclEntryPermission.WRITE_NAMED_ATTRS,
                                    AclEntryPermission.EXECUTE,
                                    AclEntryPermission.WRITE_DATA,
                                    AclEntryPermission.WRITE_ATTRIBUTES,
                                    AclEntryPermission.READ_ATTRIBUTES,
                                    AclEntryPermission.APPEND_DATA,
                                    AclEntryPermission.READ_DATA,
                                    AclEntryPermission.READ_NAMED_ATTRS,
                                    AclEntryPermission.READ_ACL,
                                    AclEntryPermission.SYNCHRONIZE,
                                    AclEntryPermission.DELETE)
                            .setFlags(AclEntryFlag.FILE_INHERIT,
                                    AclEntryFlag.DIRECTORY_INHERIT)   
                            .build();
                    return entry;
                }
            });
        } catch (IOException e) {
            throw new IllegalStateException("Unable to grant access for " + folder.toString() + " to " + user.getName(), e);
        }
    }
    

    您必须重写visitFile()和preVisitDirectory(),以便更改文件和文件夹的权限,尽管您可以用postVisitDirectory()替换preVisitDirectory()