在没有SPnego的情况下访问kerberos可以保护WebHDFS

时间:2016-05-26 11:05:58

标签: java hadoop kerberos webhdfs

我有一个使用WebHDFS管理HDFS的工作应用程序。 我需要能够在Kerberos安全集群上执行此操作。

问题是,没有库或扩展来协商我的应用程序的票证,我只有一个基本的HTTP客户端。

是否可以创建一个可以处理票证交换的Java服务,一旦获得服务票证,只需将其传递给应用程序以便在HTTP请求中使用? 换句话说,我的应用程序会要求Java服务协商票证,它会将服务票证以字符串或原始字符串形式返回给我的应用程序,而应用程序只会将其附加到HTTP请求中吗?

编辑:对于HTTPfs,是否有像@SamsonScharfrichter这样的优雅解决方案? (据我所知,它不支持委托令牌)

编辑:嗨,大家好,我还是完全输了。我试图弄清楚Hadoop-auth客户端没有任何运气。你能再帮我一次吗?我已经花了几个小时阅读它而没有运气。 这些例子说:

* // establishing an initial connection
*
* URL url = new URL("http://foo:8080/bar");
* AuthenticatedURL.Token token = new AuthenticatedURL.Token();
* AuthenticatedURL aUrl = new AuthenticatedURL();
* HttpURLConnection conn = new AuthenticatedURL(url, token).openConnection();
* ....
* // use the 'conn' instance
* ....

我已经失去了。我需要什么初始连接?怎么可以

new AuthenticatedURL(url, token).openConnection();

拿两个参数?这种情况没有构造函数。 (我因此得到错误)。委托人不应指定某个地方吗?这可能不会那么容易。

    URL url = new URL("http://<host>:14000/webhdfs/v1/?op=liststatus");
    AuthenticatedURL.Token token = new AuthenticatedURL.Token();

    HttpURLConnection conn = new AuthenticatedURL(url, token).openConnection(url, token);

2 个答案:

答案 0 :(得分:4)

使用Java代码和Hadoop Java API打开Kerberized会话,获取会话的委托令牌,并将该令牌传递给其他应用程序 - 正如@tellisnz所建议的那样 - 有一个缺点:Java API需要相当多的依赖(即很多JAR,加上Hadoop本机库)。如果你在Windows上运行应用程序,特别是这将是一个艰难的过程。

另一种选择是使用Java代码和WebHDFS来运行单个SPNEGOed查询和 GET 代理令牌,然后将其传递给其他应用程序 - 该选项需要绝对没有Hadoop库在您的服务器上。准系统版本就像

URL urlGetToken = new URL("http://<host>:<port>/webhdfs/v1/?op=GETDELEGATIONTOKEN") ;
HttpURLConnection cnxGetToken =(HttpURLConnection) urlGetToken.openConnection() ;
BufferedReader httpMessage = new BufferedReader( new InputStreamReader(cnxGetToken.getInputStream()), 1024) ;
Pattern regexHasToken =Pattern.compile("urlString[\": ]+(.[^\" ]+)") ;
String httpMessageLine ;
while ( (httpMessageLine =httpMessage.readLine()) != null)
{ Matcher regexToken =regexHasToken.matcher(httpMessageLine) ;
  if (regexToken.find())
  { System.out.println("Use that template: http://<Host>:<Port>/webhdfs/v1%AbsPath%?delegation=" +regexToken.group(1) +"&op=...") ; }
}
httpMessage.close() ;

我用来从Windows Powershell脚本(甚至是Excel宏)访问HDFS的内容。警告:在Windows中,您必须动态创建Kerberos TGT,方法是将指向相应keytab文件的JAAS配置传递给JVM。但无论如何,这个警告也适用于Java API。

答案 1 :(得分:0)

您可以查看hadoop-auth client并创建一个执行第一次连接的服务,然后您就可以获取授权&#39;和&#39; X-Hadoop-Delegation-Token&#39;标题和Cookie,并将其添加到您的基本客户的请求。

首先,您需要在运行之前使用kinit对应用程序进行身份验证。否则,您将不得不为您的用户执行JAAS登录,this tutorial提供了有关如何执行该操作的非常好的概述。

然后,要登录WebHDFS / HttpFS,我们需要做类似的事情:

URL url = new URL("http://youhost:8080/your-kerberised-resource");
AuthenticatedURL.Token token = new AuthenticatedURL.Token();
HttpURLConnection conn = new AuthenticatedURL().openConnection(url, token);

String authorizationTokenString = conn.getRequestProperty("Authorization");
String delegationToken = conn.getRequestProperty("X-Hadoop-Delegation-Token");
...
// do what you have to to get your basic client connection
...
myBasicClientConnection.setRequestProperty("Authorization", authorizationTokenString);
myBasicClientConnection.setRequestProperty("Cookie", "hadoop.auth=" + token.toString());
myBasicClientConnection.setRequestProperty("X-Hadoop-Delegation-Token", delegationToken);