用户操作文件的权限检查器——PermissionChecker
来源:互联网 发布:建e全景软件 编辑:程序博客网 时间:2024/06/06 01:29
在HDFS中,也提供了类似于linux文件系统中的文件操作权限管理功能,当我们在HDFS中创建一个文件/目录的时候,一般会为这个文件/目录附加对应的创建者、操作权限码。这里的操作权限码与linux中文件操作模式是完全一样的,如:0x777。那么,当一个客户端在对一个文件/目录进行操作(创建一个文件,读、写文件等)之前,先要对这个客户端进行操作权限的验证。其实,一个用户在使用HDFS提供的客户端来访问HDFS的时候,这个客户端是具有某个用户登录的,它和HDFS的NameNode节点连接的时候会把这个用户信息发送NameNode,在NameNode节点上,我也可以配置一个超用户和一个超用户组信息,如图所示:
首先在这里要说的就是客户端的用户信息的配置,这个用户信息可以来自客户端的配置文件core-site.xml也可以来自当前操作系统的登录用户,但是优先考虑配置文件core-site.xml中的用户信息,对应的配置项为:hadoop.job.ugi,这个配置项的值可以是一个用户名和一个用户组,或者是一个用户名和多个用户组。如果配置文件没有配置登录用户信息的话,就会自动执行系统的shell命令whoami、bash -c groups来分别获取当前系统的用户名和用户所属的组。在NameNode节点上超用户信息配置同客户端的用户配置是相同的,而超用户组的信息只能通过配置文件hdfs-site来配置了,对应的配置项为:dfs.permissions.supergroup。
刚才说过,当用户需要对某个文件进的时候就需要先验证该用户对该文件是否具有对应的操作权限,那么这个工作就交由权限检查器——PermissionChecker来处理了。
1.为客户端用户创建一个权限检查器
PermissionChecker(String fsOwner, String supergroup) throws AccessControlException{ //获取客户端的用户信息 UserGroupInformation ugi = UserGroupInformation.getCurrentUGI(); if (LOG.isDebugEnabled()) { LOG.debug("ugi=" + ugi); } if (ugi != null) { user = ugi.getUserName();//客户端的用户名 groups.addAll(Arrays.asList(ugi.getGroupNames()));//客户端的用户所属的组 isSuper = user.equals(fsOwner) || groups.contains(supergroup);//判断用户是不是超用户 } else { throw new AccessControlException("ugi = null"); } }在多线程的环境下,NameNode是如何准确地获取到当前客户端对应的用户信息的,HDFS采用了JAAS技术来实现,在这里,我并不打算详细描述。
2.检查客户端用户是否有权限操作某文件
void checkPermission(String path, INodeDirectory root, boolean doCheckOwner, FsAction ancestorAccess, FsAction parentAccess, FsAction access, FsAction subAccess) throws AccessControlException { if (LOG.isDebugEnabled()) { LOG.debug("ACCESS CHECK: " + this + ", doCheckOwner=" + doCheckOwner + ", ancestorAccess=" + ancestorAccess + ", parentAccess=" + parentAccess + ", access=" + access + ", subAccess=" + subAccess); } synchronized(root) { INode[] inodes = root.getExistingPathINodes(path);//获取文件的所有父节点 int ancestorIndex = inodes.length - 2; for(; ancestorIndex >= 0 && inodes[ancestorIndex] == null; ancestorIndex--); checkTraverse(inodes, ancestorIndex); if (ancestorAccess != null && inodes.length > 1) { check(inodes, ancestorIndex, ancestorAccess); } if (parentAccess != null && inodes.length > 1) { check(inodes, inodes.length - 2, parentAccess); } if (access != null) { check(inodes[inodes.length - 1], access); } if (subAccess != null) { checkSubAccess(inodes[inodes.length - 1], subAccess); } if (doCheckOwner) { checkOwner(inodes[inodes.length - 1]); } } } private void checkOwner(INode inode) throws AccessControlException { if (inode != null && user.equals(inode.getUserName())) { return; } throw new AccessControlException("Permission denied"); } private void checkTraverse(INode[] inodes, int last) throws AccessControlException { for(int j = 0; j <= last; j++) { check(inodes[j], FsAction.EXECUTE); } } private void checkSubAccess(INode inode, FsAction access ) throws AccessControlException { if (inode == null || !inode.isDirectory()) { return; } Stack<INodeDirectory> directories = new Stack<INodeDirectory>(); for(directories.push((INodeDirectory)inode); !directories.isEmpty(); ) { INodeDirectory d = directories.pop(); check(d, access); for(INode child : d.getChildren()) { if (child.isDirectory()) { directories.push((INodeDirectory)child); } } } } private void check(INode[] inodes, int i, FsAction access) throws AccessControlException { check(i >= 0? inodes[i]: null, access); } private void check(INode inode, FsAction access) throws AccessControlException { if (inode == null) { return; } FsPermission mode = inode.getFsPermission();//获取该文件的权限操作码 if (user.equals(inode.getUserName())) { //用户名相同 if (mode.getUserAction().implies(access)) { return; } } else if (groups.contains(inode.getGroupName())) { //用户组相同 if (mode.getGroupAction().implies(access)) { return; } } else { //other class if (mode.getOtherAction().implies(access)) { return; } } throw new AccessControlException("Permission denied: user=" + user + ", access=" + access + ", inode=" + inode); }
很多初学者在操作HDFS中的文件时经常会遇到AccessControlException异常,但是这个文件其实是自己之前建立的,按理说不可能出现“无权访问”这样的问题的,而造成这个异常的一个可能的场景是:没有通过配置文件来配置客户端的用户信息,用OS的用户user1创建了文件,之后又用OS的用户user2来删除该文件,此时却发现无权删除该文件,所以出现这一类异常的根本原因就是客户端的登录用户信息配置不正确,导致他无法操作自己想要的文件。如果出现这类操作异常的话,请仔细阅读本文。
- 用户操作文件的权限检查器——PermissionChecker
- 用户操作文件的权限检查
- 检查 ABAP/4 程序用户的 权限
- postgresql 用户的操作权限
- Linux成长之路(一)——基本概念及操作、用户及文件权限管理
- Linux成长之路(一)——基本概念及操作、用户及文件权限管理
- Linux——用户及文件权限
- 学习linux之用户-文件-权限操作
- linux基本操作---用户以及文件权限
- 文件权限的操作
- 文件权限的操作
- linux学习之(四)-用户、组的操作,给文件文件夹设置组,更改目录权限、文件权限
- Android PermissionChecker 权限全面详细分析和解决方案
- Linux修改用户的操作权限
- MYSQL用户和权限的相关操作
- mysql 中用户与权限的操作
- Ambari-Server Rest API处理3(用户鉴权、操作权限检查管理)
- 文件权限的基本操作
- matlab 画圆~
- 在linux下安装was 6.1程序 Cannot get canonical host name for server
- 正则表达式解惑
- PE详解之IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用(PE详解03)
- HTML条件注释
- 用户操作文件的权限检查器——PermissionChecker
- C/S自动更新软件
- PE详解之区块表(节表)和区块(节)(PE详解04)
- 不指定主窗口,程序不能退出消息泵
- PE详解之区块表(节表)和区块(节)续(PE详解05)
- 在MFC中如何使用PreTranslateMessage
- JAVA网络编程Socket常见问题 【长连接专题】
- POJ 2636 Electrical Outlets(我的水题之路——水,电器接头)
- win7 64位操作 SQLlite +VS2010