httpclient访问httpfs服务(有Kerberos认证)

来源:互联网 发布:零云cms 编辑:程序博客网 时间:2024/06/10 05:06

场景:cdh集群已经添加kerberos认证,但是需要访问httpfs服务,怎么办?

如下实现:

1、引入maven

4.3.34.3.3        !--httpclient-->    org.apache.httpcomponents    httpclient    ${httpclient.version}    org.apache.httpcomponents    httpcore    ${httpcore.version}

2、代码:

package hadoop.other;import java.io.IOException;import java.io.InputStream;import java.security.Principal;import java.security.PrivilegedAction;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.Set;import javax.security.auth.Subject;import javax.security.auth.kerberos.KerberosPrincipal;import javax.security.auth.login.AppConfigurationEntry;import javax.security.auth.login.Configuration;import javax.security.auth.login.LoginContext;import org.apache.commons.io.IOUtils;import org.apache.http.HttpResponse;import org.apache.http.auth.AuthSchemeProvider;import org.apache.http.auth.AuthScope;import org.apache.http.auth.Credentials;import org.apache.http.client.HttpClient;import org.apache.http.client.config.AuthSchemes;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpUriRequest;import org.apache.http.config.Lookup;import org.apache.http.config.RegistryBuilder;import org.apache.http.impl.auth.SPNegoSchemeFactory;import org.apache.http.impl.client.BasicCredentialsProvider;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClientBuilder;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * Created by yangjf on 2017/5/13 * Update date: * Time: 18:33 * Describle : * Result of Test:测试通过 * Command: * Email: jifei.yang@ngaa.com.cn */public class HttpClientGetEx {    public static Logger logger= LoggerFactory.getLogger(HttpClientGetEx.class);    private String principal ;    private String keyTabLocation ;    public HttpClientGetEx() {}    public HttpClientGetEx(String principal, String keyTabLocation) {        super();        this.principal = principal;        this.keyTabLocation = keyTabLocation;    }    public HttpClientGetEx(String principal, String keyTabLocation, boolean isDebug) {        this(principal, keyTabLocation);        if (isDebug) {            System.setProperty("sun.security.spnego.debug", "true");            System.setProperty("sun.security.krb5.debug", "true");        }    }    public HttpClientGetEx(String principal, String keyTabLocation, String krb5Location, boolean isDebug) {        this(principal, keyTabLocation, isDebug);        System.setProperty("java.security.krb5.conf", krb5Location);    }    //模拟curl使用kerberos认证    private static HttpClient buildSpengoHttpClient() {        HttpClientBuilder builder = HttpClientBuilder.create();        Lookup authSchemeRegistry = RegistryBuilder.create().                register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true)).build();        builder.setDefaultAuthSchemeRegistry(authSchemeRegistry);        BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();        credentialsProvider.setCredentials(new AuthScope(null, -1, null), new Credentials() {            @Override            public Principal getUserPrincipal() {                return null;            }            @Override            public String getPassword() {                return null;            }        });        builder.setDefaultCredentialsProvider(credentialsProvider);        CloseableHttpClient httpClient = builder.build();        return httpClient;    }    public HttpResponse callRestUrl(final String url,final String userId) {        logger.warn(String.format("Calling KerberosHttpClient %s %s %s",this.principal, this.keyTabLocation, url));        Configuration config = new Configuration() {            @SuppressWarnings("serial")            @Override            public AppConfigurationEntry[] getAppConfigurationEntry(String name) {                return new AppConfigurationEntry[] { new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",                        AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new HashMap() {                    {                        put("useTicketCache", "false");                        put("useKeyTab", "true");                        put("keyTab", keyTabLocation);                        //Krb5 in GSS API needs to be refreshed so it does not throw the error                        //Specified version of key is not available                        put("refreshKrb5Config", "true");                        put("principal", principal);                        put("storeKey", "true");                        put("doNotPrompt", "true");                        put("isInitiator", "true");                        put("debug", "true");                    }                }) };            }        };        Set princ = new HashSet(1);        princ.add(new KerberosPrincipal(userId));        Subject sub = new Subject(false, princ, new HashSet(), new HashSet());        try {            //认证模块:Krb5Login            LoginContext lc = new LoginContext("Krb5Login", sub, null, config);            lc.login();            Subject serviceSubject = lc.getSubject();            return Subject.doAs(serviceSubject, new PrivilegedAction() {                HttpResponse httpResponse = null;                @Override                public HttpResponse run() {                    try {                        HttpUriRequest request = new HttpGet(url);                        HttpClient spnegoHttpClient = buildSpengoHttpClient();                        httpResponse = spnegoHttpClient.execute(request);                        return httpResponse;                    } catch (IOException ioe) {                        ioe.printStackTrace();                    }                    return httpResponse;                }            });        } catch (Exception le) {            le.printStackTrace();        }        return null;    }    public static void main(String[] args) throws UnsupportedOperationException, IOException {        //curl -i --negotiate -u : "http://hadoop2:50070/webhdfs/v1/user/jifei.yang?op=liststatus"        //curl -i --negotiate -u : "http://hadoop2:50070/webhdfs/v1/user/jifei.yang/db/mydb_impala/monitor02/customer_id=010/day=monday/user.txt?op=open"        String user ="log2hadoop@BAIDU.COM";        String keytab="F:/log2hadoop.keytab";        String krb5Location="F:/krb5.conf";        HttpClientGetEx restTest = new HttpClientGetEx(user,keytab,krb5Location, false);        //查看文件或者文件夹列表        String url_liststatus="http://hadoop2:50070/webhdfs/v1/user/jifei.yang?op=liststatus";        //查看位置        String url_get_block_locations="http://hadoop2:50070/webhdfs/v1/user/jifei.yang/db/mydb_impala/monitor02/customer_id=010/day=monday/user.txt?op=get_block_locations";        //查看文件内容        String url_open_file="http://hadoop2:50070/webhdfs/v1/user/jifei.yang/db/mydb_impala/monitor02/customer_id=010/day=monday/user.txt?op=open";//        HttpResponse response = restTest.callRestUrl(url_liststatus,user);//        HttpResponse response = restTest.callRestUrl(url_get_block_locations,user);        HttpResponse response = restTest.callRestUrl(url_open_file,user);        InputStream is = response.getEntity().getContent();        logger.warn("Status code " + response.getStatusLine().getStatusCode());        logger.warn("message is :"+Arrays.deepToString(response.getAllHeaders()));        logger.warn("字符串:\n"+new String(IOUtils.toByteArray(is), "UTF-8"));    }}