【问题标题】:authenticate with ntlm (or kerberos) using java UrlConnection使用 java UrlConnection 使用 ntlm(或 kerberos)进行身份验证
【发布时间】:2026-01-30 19:50:01
【问题描述】:

我需要使用 java 使用 REST Web 服务,传递域用户帐户的凭据。

现在我正在用经典的 asp 做它


set xmlHttp = server.createObject( "msxml2.serverxmlhttp" )
xmlHttp.open method, url, false, domain & "\" & user, password
xmlHttp.send body
out = xmlHttp.responseText
set xmlHttp = nothing

和asp.net



HttpWebRequest request = (HttpWebRequest) WebRequest.Create( url );

request.Credentials = new NetworkCredential(user, password, domain);

request.Method = WebRequestMethods.Http.Get

HttpWebResponse response = (HttpWebResponse) request.GetResponse();

StreamReader outStream = new StreamReader( response.GetResponseStream(), Encoding.UTF8) ;

output = outStream.ReadToEnd();

我怎样才能用 java 实现呢?考虑到我没有使用当前登录用户的凭据,我指定了域帐户(我有密码)

请告诉我它和经典的 asp 和 asp.net 一样简单......

【问题讨论】:

    标签: java authentication kerberos ntlm httpurlconnection


    【解决方案1】:

    根据this page,您可以使用内置的 JRE 类,但需要注意的是早期版本的 Java 只能在 Windows 机器上执行此操作。

    但是,如果您愿意接受第 3 方依赖项,那么 IMO Apache Commons HttpClient 3.x 是不错的选择。 Here 是使用身份验证的文档,包括 NTLM。一般来说,HttpClient 是一个功能更强大的库。

    HttpClient的最新版本是4.0,但是显然这个版本does not support NTLM这个版本requires a tiny bit of extra work

    这是我认为代码的样子,虽然我还没有尝试过:

    HttpClient httpClient = new HttpClient();
    httpClient.getState().setCredentials(AuthScope.ANY, new NTCredentials(user, password, hostPortionOfURL, domain));
    GetMethod request = new GetMethod(url);
    BufferedReader reader = new InputStreamReader(request.getResponseBodyAsStream());
    

    祝你好运。

    【讨论】:

    • 嘿,马特,非常感谢您的回答,但我想知道是否可以使用内置 JRE 类,使用 kerberos 而不是 ntlm...我的意思是,kerberos 不是像 NTLM 这样的 ptopietary 东西......
    • 最后听说,Apache 客户端不支持 NTLMv2。他们不愿意使用 JCIFS,因为 a)他们声称它的 LGPLv2 与他们的许可证不兼容,并且 b)他们通常厌倦了 MS 的东西。但这没关系,因为如果您想与 Microsoft 互操作,NTLM 是身份验证机制的共同点。如果客户端无权访问域控制器或时间同步已关闭或 DNS 不完全正确或...等,Kerberos 将无法工作。
    • 嗨 ioplex。我不确定你在哪里听到的,但这是不正确的。请查看我链接到的文档。我已经成功地将 NTLM 与 HttpClient 3.x 和 4.0 一起使用。
    • 第一个链接坏了。
    【解决方案2】:

    一个兼容 java.net.URLStreamHandler 和 java.net.URL 的解决方案是 com.intersult.net.http.NtlmHandler:

    NtlmHandler handler = new NtlmHandler();
    handler.setUsername("domain\\username");
    handler.setPassword("password");
    URL url = new URL(null, urlString, handler);
    URLConnection connection = url.openConnection();
    

    您也可以在 url.openConnection(proxy) 中使用 java.net.Proxy。

    使用 Maven 依赖:

        <dependency>
            <groupId>com.intersult</groupId>
            <artifactId>http</artifactId>
            <version>1.1</version>
        </dependency>
    

    【讨论】:

      【解决方案3】:

      看看 SPNEGO HTTP Servlet Filter 项目中的 SpnegoHttpURLConnection 类。这个项目也有一些例子。

      这个项目有一个client library,它几乎可以完成您在示例中所做的事情。

      看看这个来自 javadoc 的例子...

       public static void main(final String[] args) throws Exception {
           final String creds = "dfelix:myp@s5";
      
           final String token = Base64.encode(creds.getBytes());
      
           URL url = new URL("http://medusa:8080/index.jsp");
      
           HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      
           conn.setRequestProperty(Constants.AUTHZ_HEADER
                   , Constants.BASIC_HEADER + " " + token);
      
           conn.connect();
      
           System.out.println("Response Code:" + conn.getResponseCode());
       }
      

      【讨论】:

      • 实际上可以在没有任何代码库的情况下使用 conn.setRequestProperty("Authorization", "Basic" + " " + token);
      • 这不能回答问题。此解决方案适用于基本身份验证,但不适用于 Kerbos 或 NTLM 身份验证。