如何使用 Java 在 Windows 文件上设置 "modify" ACL
How to set "modify" ACL on a Windows file using Java
如何使用 Java 7 的文件 API 设置 Windows ACL,使其模拟添加 user/group 和以下选项:
例如,在 OS 属性对话框中,您可以 select 以下内容进行基本写入访问:
- ☑ 修改
- ☑ 读取和执行(自动selected)
- ☑ 列出文件夹内容(自动selected)
- ☑ 阅读(自动selected)
- ☑ 写入(自动selected)
然而,当我使用 Java 7 的文件 API 使用类似的选项时,它反而 selects:
- ☑ 特别
- ☑ 高级(不编辑,单击用户或组,查看)
- 显示高级权限
- 高级权限
- ☑(一堆复选框)
这不仅更难管理(遍历对话框更容易遗漏某些东西),而且它的行为与简单地单击那些框不同。一些 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);
我能够通过创建一个我想模仿的文件夹来模仿 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();
... 现在 "Modify" 完全按照需要进行了检查。
如何使用 Java 7 的文件 API 设置 Windows ACL,使其模拟添加 user/group 和以下选项:
例如,在 OS 属性对话框中,您可以 select 以下内容进行基本写入访问:
- ☑ 修改
- ☑ 读取和执行(自动selected)
- ☑ 列出文件夹内容(自动selected)
- ☑ 阅读(自动selected)
- ☑ 写入(自动selected)
然而,当我使用 Java 7 的文件 API 使用类似的选项时,它反而 selects:
- ☑ 特别
- ☑ 高级(不编辑,单击用户或组,查看)
- 显示高级权限
- 高级权限
- ☑(一堆复选框)
- ☑ 高级(不编辑,单击用户或组,查看)
这不仅更难管理(遍历对话框更容易遗漏某些东西),而且它的行为与简单地单击那些框不同。一些 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);
我能够通过创建一个我想模仿的文件夹来模仿 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();
... 现在 "Modify" 完全按照需要进行了检查。