使用httpclient 4.2.1进行NTLM身份验证

时间:2012-10-04 12:07:02

标签: java ntlm apache-httpclient-4.x

我需要对需要NTLM身份验证的URL执行HTTP GET。我可以在MacBook Pro上使用Firefox或Chrome访问该URL。浏览器要求输入用户名/密码组合并且它有效。我现在正尝试使用HttpClient从Groovy做同样的事情。我跟着NTLM support guide,但我总是得到401 Unauthorized。回复中还有这句话:

  

您无权使用以下方式查看此目录或页面   您提供的凭据,因为您的Web浏览器正在发送   未配置Web服务器的WWW-Authenticate头字段   接受。

我在这段代码中尝试了服务器名和域的各种组合(远程windows pc不在域上),但我总是得到相同的响应。

httpclient.getCredentialsProvider().setCredentials(
new AuthScope("myserver", -1), 
new NTCredentials("username", "password", "MYSERVER", "MYDOMAIN"));

有人遇到同样的问题并设法解决了吗?请注意,这是一个使用IIS的外部程序,所以我认为我不能在那里更改任何设置。

编辑:

与我所说的不同,我设法更改IIS中的安全设置以接受BASIC认证,所以我不再有问题了。

2 个答案:

答案 0 :(得分:0)

编辑:

根据我设置Kerberos或NTLM的经验(两者都是单点登录),当您已经登录系统时,您根本不必输入用户名/密码。

我很确定当浏览器询问用户名/密码组合时,根本不是NTLM身份验证。服务器端应用程序很可能具有HTTP Basic Digest的回退方案(这就是它显示用户名/密码组合的原因)。使用NTLM,您将永远不必输入您的用户名/密码(主体/凭证),因为服务器将通过浏览器,操作系统,服务器和Active Directory服务器之间的协商机制识别您的身份。

如果您的MacBook Pro在OS / X上运行,您还需要将OS / X添加到域中。 您的服务器还需要位于添加客户端OS / X的同一域中。 这可能不是一个简单的案例。可能需要一些外部工具/驱动程序。 This one可能是一个很好的候选人(但我没试过)。

NTLM需要客户端都是与服务器相同的域的成员,因此两者都需要在Active Directory域中注册。如果您的服务器不在域中,那么这将是另一组问题。

为了让您的浏览器与NTLM一起使用,您需要安装插件(ntlmauth-plugin?)。但我还没有在MacOS / X上尝试过。即使在Windows中,您仍然需要一个插件才能使用NTLM成功运行Firefox。

答案 1 :(得分:0)

HttpClient对我不起作用,但最终下面的代码工作了。 参考 - http://docs.oracle.com/javase/7/docs/technotes/guides/net/http-auth.html

供快速参考 -

public static String getResponse(String url, String userName, String password) throws IOException {
Authenticator.setDefault(new Authenticator() {
  @Override
  public PasswordAuthentication getPasswordAuthentication() {
    System.out.println(getRequestingScheme() + " authentication");
    return new PasswordAuthentication(userName, password.toCharArray());
  }
});

URL urlRequest = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urlRequest.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("GET");

StringBuilder response = new StringBuilder();
InputStream stream = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(stream));
String str = "";
while ((str = in.readLine()) != null) {
  response.append(str);
}
in.close();

return response.toString();

}