hdfsAPI访问Kerberos集群

隶属于文章系列:大数据安全实战 https://www.jianshu.com/p/76627fd8399c


import com.kingdee.bigdata.hina.conf.ConfigModelSynchro;
import com.kingdee.bigdata.hina.constant.Constants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.security.UserGroupInformation;
import java.io.IOException;
import java.net.URI;

public class HdfsUtil {
    protected static final Log log = LogFactory.getLog(HdfsUtil.class);
    FileSystem fs = null;
    public HdfsUtil(){}
    public HdfsUtil(String hdfspath) {
            String path = "hdfs://cluster2018:8020" + hdfspath;
            //log.debug("hdfs path:" + path);
            FileStatus fileStatus = null;
            //System.setProperty("hadoop.home.dir", model.getHadoopHome());
            Configuration conf = new Configuration();
            //conf.set("fs.defaultFS", "hdfs://10.247.24.53:8020");
            conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs " +
                    ".DistributedFileSystem");
            if (ConstantPool.KerberEnabled) {
                setKerberos(conf);
                try {
                    fs = FileSystem.get(URI.create(path), conf);
                } catch (Exception e) {
                    log.error("get the file failed", e);
                }

            } else {
                try {
                    fs = FileSystem.get(URI.create(path), conf);
                } catch (Exception e) {
                    log.error("get the file failed", e);
                }
            }
        }

    public FileSystem getFs() {
        return fs;
    }

    private void setKerberos(Configuration conf ) {
        conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem
                .class.getName());

        if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
            System.setProperty("java.security.krb5.conf",
                    com.kingdee.bigdata.hina.constant.Constants.Krb5_Conf);
        } else {
             /*linux系统可不设,其会自动去寻找 /etc/krb5.conf*/
            System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
        }

        conf.set("hadoop.security.authentication", "kerberos");
        UserGroupInformation.setConfiguration(conf);
        try {
            UserGroupInformation.loginUserFromKeytab(Constants.HDFS_User, Constants.Hdfs_Key_Tab);
        } catch (Exception e) {
            log.error("身份认证异常: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Proxy user的配置在参考文档中可以看到。当集群是安全模式是,超级用户要配置Kerberos凭证。
下面用hive用户的凭证来代理hello用户。

public static void main(String[] args) throws InterruptedException {

        //Create ugi for joe. The login user is 'super'.
        UserGroupInformation ugi =
                null;
        final HdfsUtil hu = new HdfsUtil("/tmp");
        try {
            ugi = UserGroupInformation.createProxyUser("hello",
                    UserGroupInformation.getLoginUser());
            ugi.doAs(new PrivilegedExceptionAction<String>() {
                public String run() throws Exception {
                    //Submit a job
//                  JobClient jc = new JobClient(conf);
//                  jc.submitJob(conf);

                    //OR access hdfs
                    FileSystem fs = hu.getFs();
                    String someFilePath = "hdfs://cluster2018:8020/tmp/";
                    FileStatus[] listStatus = fs.listStatus(new Path
                            (someFilePath));
                    for (int i = 0; i < listStatus.length; i++) {
                        System.out.println(listStatus[i].toString());
                    }
                    fs.mkdirs(new Path("hdfs://cluster2018:8020/tmp/proxy123" +
                            ""));
                    fs.close();
                    return "";
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

然而创建完查看创建的文件:
drwxr-xr-x - hive supergroup 0 2018-04-23 19:35 /tmp/proxy123

当使用hive的凭证时,实际在用hive的权限在操作。

Delegation Tokens(代理token)
在分布式系统,如HDFS 或者MapReduce,会有很多客户端和服务器之间的交互,这些交互都必须要进行认证,例如:在一个HDFS读操作的过程中,需要多次调用namenode与datanode,
如果对每一次call,都使用三步式Kerberos认证,那么无疑会增加很高的负载,。Hadoop使用代理token,这种token在生成之后,就不会再和kerberos中心进行交互。Delegation Tokens
有Hadoop代表用户生成并使用,所以这里不要你进行签名认证。
一个Delegation Token,有NameNode产生,可以被认为是一个在client与服务器之间共享的secret,在client与server之间的第一次RPC调用的时候,并没有Delegation Token生成,所以它必须要经过kerberos进行认证,client会从namenode中获得一个Delegation Token。
如果client想进行HDFS blocks进行操作,client会使用一个特殊的Delegation Token,叫做block access token。这个token是namenode在client进行metadata请求的时候,作为给client的相应传递给client。client使用这个token来向datanode认证自己。这是可能是因为namenode会和datanode之间共享这个token,所以这是Block就只能被持有这个token的客户端进行访问了,要启用这token功能,需要设置dfs.block.access.token.enable =true。

参考:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 177,897评论 25 709
  • 1. 作文开头 2. 语文背诵巩固 3. 练歌准备比赛 抱歉唉,昨天忘了发了,真的觉得这样很不好。
    完美直线桑阅读 244评论 0 0
  • 抛开这部片子的政治正确和种族问题,我觉得它获得奥斯卡真的实至名归。而豆瓣评分却只有7.2分,让我觉得它被低估了,它...
    木槿楠阅读 835评论 1 3
  • 南北两宋传建盏, 形状各异传百年。 黛染霜花质雅优, 豪饮香茗情趣然。 斑斓纹形多变换, 立体层次金属感。 光线强...
    绿里是我阅读 217评论 0 0
  • 今天为所有认识的不认识的朋友们建了一个群,顺带还有购物优惠,起初建群时很担心会不会让大家讨厌,开始就以为大家谋优惠...
    Mela弓慧园阅读 296评论 0 0

友情链接更多精彩内容