下一节中描述的代码示例适用于以下用例。
用户名为“ super”的超级用户希望代表用户joe提交作业并访问hdfs。超级用户具有kerberos凭证,但joe用户没有任何凭证。这些任务需要以用户joe的身份运行,而对namenode的任何文件访问都必须以用户joe的身份进行。要求用户joe可以在通过super的kerberos凭据进行身份验证的连接上连接到namenode或job tracker。换句话说,super正在冒充用户joe。
某些产品(例如Apache Oozie)需要此功能。
在此示例中,super的凭据用于登录,并为joe创建了代理用户ugi对象。在此代理用户ugi对象的doAs方法内执行操作。
... //为joe创建ugi。登录用户为“超级”。 UserGroupInformation ugi = UserGroupInformation.createProxyUser(“ joe”,UserGroupInformation.getLoginUser()); ugi.doAs(new PrivilegedExceptionAction <Void>(){ public Void run()引发异常{ //提交工作 JobClient jc = new JobClient(conf); jc.submitJob(conf); //或访问hdfs FileSystem fs = FileSystem.get(conf); fs.mkdir(someFilePath); } }
您可以使用属性hadoop.proxyuser。$ superuser.hosts以及hadoop.proxyuser。$ superuser.groups和hadoop.proxyuser。$ superuser.users中的一个或两个来配置代理用户。
通过在core-site.xml中进行如下指定,名为super的超级用户只能从host1和host2连接来模拟属于group1和group2的用户。
<属性> <name> hadoop.proxyuser.super.hosts </ name> <value> host1,host2 </ value> </ property> <属性> <name> hadoop.proxyuser.super.groups </ name> <value> group1,group2 </ value> </ property>
如果不存在这些配置,则将无法进行模拟并且连接将失败。
如果更宽松的安全性是首选,通配符*可用于允许来自任何主机或任何用户的模拟。例如,通过在core-site.xml中进行如下指定,从任何主机访问的名为oozie的用户都可以假冒属于任何组的任何用户。
<属性> <name> hadoop.proxyuser.oozie.hosts </ name> <value> * </ value> </ property> <属性> <name> hadoop.proxyuser.oozie.groups </ name> <value> * </ value> </ property>
该hadoop.proxyuser。$ superuser.hosts接受IP地址,CIDR格式和/或主机名的IP地址范围的列表。例如,通过以下指定,从10.222.0.0-15和10.113.221.221范围内的主机进行超级访问的用户可以模拟user1和user2。
<属性> <name> hadoop.proxyuser.super.hosts </ name> <value> 10.222.0.0/16,10.113.221.221 </ value> </ property> <属性> <name> hadoop.proxyuser.super.users </ name> <value> user1,user2 </ value> </ property>
如果集群以安全模式运行,则超级用户必须具有kerberos凭据才能模拟其他用户。
它不能为此功能使用委托令牌。如果超级用户将自己的委派令牌添加到代理用户ugi,将是错误的,因为它将允许代理用户使用超级用户的特权连接到服务。
但是,如果超级用户确实希望将委派令牌授予joe,则它必须首先模拟joe并获得joe的委派令牌,与上面的代码示例相同,然后将其添加到joe的ugi中。这样,委派令牌将拥有者为joe。