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

Accessing kerberos secured WebHDFS without SPnego

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

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

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

编辑:是否有类似@SamsonScharfrichter 为 HTTPfs 描述的优雅解决方案? (据我所知,它不支持委托令牌)

EDIT2:大家好,我还是完全迷路了。我试图在没有任何运气的情况下找出 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);

您可以看一下 hadoop-auth client 并创建一个进行第一个连接的服务,然后您也许可以获取 'Authorization' 和 'X-Hadoop-Delegation-Token' headers 和 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);

使用 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,方法是向 JVM 传递指向适当密钥表文件的 JAAS 配置。但无论如何,该警告也适用于 Java API。