[NIO.2] 第十六篇 属性视图之 ACL View
程序员文章站
2022-04-28 17:29:58
...
一个访问控制列表(ACL)就是一组用来精确控制访问文件的权限列表。ACL 控制着文件所有者、权限、以及各种类型的文件标识。NIO.2 提供了 AclFileAttributeView 来支持 ACL。
使用 Files.getFileAttributeView() 获取 ACL
如果你没有见过 ACL 的内容,可以试试下面这段代码,使用了 Files.getFileAttributeView() 来获取 ACL,调用这个方法的返回值类型是 List<AclEntry>:
使用 Files.getAttribute() 获取 ACL
可以使用通用方法 getAttribute() 来获取 ACL:
ACL 属性视图支持以下属性名称:
访问属性的通用结构是 [view-name:]attribute-name,在这里 view-name 是 acl。
读取 ACL 记录
前面的两个例子演示了如何获取 ACL 列表,它们的返回值都是存放 AclEntry 对象的 List。 AclEntry 对象对应 ACL 的一个入口。每个 AclEntry 对象由下面四部分组成:
你可以用下面的代码遍历 ACL 列表,并打印出每个入口的详情,下面的例子打印出了前面例子中取得的 acllist:
下面是在 Windows 7 上运行的结果
在 ACL 中添加新的入口
可以调用 AclEntry.Builder 的 build() 方法创建一个新的 ACL 入口。如果你要为某个用户添加新的访问权限,可以通过下面的步骤:
遵照前面的步骤,下面的代码片段演示了如何为 apress 用户分配访问权限:
注意:上面的例子中使用到了用户 apress,如果你的机器上没有这个用户,会抛出 java.nio.file.attribute.UserPrincipalNotFoundException 异常。
上面的代码可以用来给已经存在的文件的 ACL 添加一个新的入口。也可以用于新创建文件的时候。
注意:因为 AclFileAttributeView 继承自 FileOwnerAttributeView,因此可以直接调用 getOwner() 和 setOwner() 方法。
文章来源:http://www.aptusource.org/2014/03/nio-2-acl-view/
使用 Files.getFileAttributeView() 获取 ACL
如果你没有见过 ACL 的内容,可以试试下面这段代码,使用了 Files.getFileAttributeView() 来获取 ACL,调用这个方法的返回值类型是 List<AclEntry>:
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.AclEntry; import java.nio.file.attribute.AclFileAttributeView; import java.util.List; … List acllist = null; Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt"); AclFileAttributeView aclview = Files.getFileAttributeView(path, AclFileAttributeView.class); try { acllist = aclview.getAcl(); } catch (IOException e) { System.err.println(e); }
使用 Files.getAttribute() 获取 ACL
可以使用通用方法 getAttribute() 来获取 ACL:
import static java.nio.file.LinkOption.NOFOLLOW_LINKS; … List acllist = null; Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt"); try { acllist = (List) Files.getAttribute(path, "acl:acl", NOFOLLOW_LINKS); } catch (IOException e) { System.err.println(e); }
ACL 属性视图支持以下属性名称:
- acl
- owner
访问属性的通用结构是 [view-name:]attribute-name,在这里 view-name 是 acl。
读取 ACL 记录
前面的两个例子演示了如何获取 ACL 列表,它们的返回值都是存放 AclEntry 对象的 List。 AclEntry 对象对应 ACL 的一个入口。每个 AclEntry 对象由下面四部分组成:
- Type:入口的类型,可用值为: ALARM, ALLOW, AUDIT, 或 DENY。
- Principal:入口允许的身份,映射 UserPrincipal 类。
- Permissions:一组权限,映射 Set。
- Flags:一组标识,表示条目如何被继承和传播,映射 Set。
你可以用下面的代码遍历 ACL 列表,并打印出每个入口的详情,下面的例子打印出了前面例子中取得的 acllist:
for (AclEntry aclentry : acllist) { System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++"); System.out.println("Principal: " + aclentry.principal().getName()); System.out.println("Type: " + aclentry.type().toString()); System.out.println("Permissions: " + aclentry.permissions().toString()); System.out.println("Flags: " + aclentry.flags().toString()); }
下面是在 Windows 7 上运行的结果
++++++++++++++++++++++++++++++++++++++++++++++++++++ Principal: BUILTIN\Administrators Type: ALLOW Permissions: [WRITE_OWNER, READ_ACL, EXECUTE, WRITE_NAMED_ATTRS, READ_ATTRIBUTES, READ_NAMED_ATTRS, WRITE_DATA, WRITE_ACL, READ_DATA, WRITE_ATTRIBUTES, SYNCHRONIZE, DELETE, DELETE_CHILD, APPEND_DATA] Flags: [] ++++++++++++++++++++++++++++++++++++++++++++++++++++ Principal: NT AUTHORITY\SYSTEM Type: ALLOW Permissions: [WRITE_OWNER, READ_ACL, EXECUTE, WRITE_NAMED_ATTRS, READ_ATTRIBUTES, READ_NAMED_ATTRS, WRITE_DATA, WRITE_ACL, READ_DATA, WRITE_ATTRIBUTES, SYNCHRONIZE, DELETE, DELETE_CHILD, APPEND_DATA] Flags: [] ++++++++++++++++++++++++++++++++++++++++++++++++++++ Principal: NT AUTHORITY\Authenticated Users Type: ALLOW Permissions: [READ_ACL, EXECUTE, READ_DATA, WRITE_ATTRIBUTES, WRITE_NAMED_ATTRS, SYNCHRONIZE, DELETE, READ_ATTRIBUTES, READ_NAMED_ATTRS, WRITE_DATA, APPEND_DATA] Flags: [] ++++++++++++++++++++++++++++++++++++++++++++++++++++ Principal: BUILTIN\Users Type: ALLOW Permissions: [READ_ACL, EXECUTE, READ_DATA, SYNCHRONIZE, READ_ATTRIBUTES, READ_NAMED_ATTRS] Flags: []
在 ACL 中添加新的入口
可以调用 AclEntry.Builder 的 build() 方法创建一个新的 ACL 入口。如果你要为某个用户添加新的访问权限,可以通过下面的步骤:
- 调用 FileSystem.getUserPrincipalLookupService() 方法查找用户。
- 获取 ACL View(前面已经介绍过)。
- 通过 AclEntry.Builder 对象创建新的入口。
- 读取 ACL(前面已经介绍过)。
- 插入新的入口(建议插入到 DENY 入口之前)。
- 调用 setAcl() 或 setAttribute() 重写 ACL。
遵照前面的步骤,下面的代码片段演示了如何为 apress 用户分配访问权限:
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.AclEntry; import java.nio.file.attribute.AclEntryPermission; import java.nio.file.attribute.AclEntryType; import java.nio.file.attribute.AclFileAttributeView; import java.nio.file.attribute.UserPrincipal; import java.util.List; import static java.nio.file.LinkOption.NOFOLLOW_LINKS; … try { //Lookup for the principal UserPrincipal user = path.getFileSystem().getUserPrincipalLookupService() //Get the ACL view AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class); //Create a new entry AclEntry entry = AclEntry.newBuilder().setType(AclEntryType.ALLOW). setPrincipal(user).setPermissions(AclEntryPermission.READ_DATA, AclEntryPermission.APPEND_DATA).build(); //read ACL List acl = view.getAcl(); //Insert the new entry acl.add(0, entry); //rewrite ACL view.setAcl(acl); //or, like this //Files.setAttribute(path, "acl:acl", acl, NOFOLLOW_LINKS); } catch (IOException e) { System.err.println(e); }
注意:上面的例子中使用到了用户 apress,如果你的机器上没有这个用户,会抛出 java.nio.file.attribute.UserPrincipalNotFoundException 异常。
上面的代码可以用来给已经存在的文件的 ACL 添加一个新的入口。也可以用于新创建文件的时候。
注意:因为 AclFileAttributeView 继承自 FileOwnerAttributeView,因此可以直接调用 getOwner() 和 setOwner() 方法。
文章来源:http://www.aptusource.org/2014/03/nio-2-acl-view/