4

We have a funny situation where basic GET HTTP request doesn't pass Windows NTLM autorization at IIS server. At the same time we have same code running on another environment which gets successfully executed.

When we repeat request via browser it gets successfully executed.

It seems that somehow Java code doesn't send correct authorization information with the request. We are trying to figure out how this can be. Classes used are from java.net package. We tried switching account to Local System under which Tomcat is running back and forth with no success.

Code is as simple as it can be:

public static String sendHttpRequest(String urlString, String method, boolean 
disconnect) {

    HttpURLConnection urlConnection = null;
    String result = null;
    try {

        URL url = new URL(urlString);

        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.addRequestProperty("Content-Length", "0");

        urlConnection.setRequestMethod(method);
        urlConnection.setUseCaches(false);

         StringBuilder sb = new StringBuilder();
        try (InputStream is = urlConnection.getInputStream()) {

             InputStream buffer = new BufferedInputStream(is);
            Reader reader = new InputStreamReader(buffer, "UTF-8");
            int c;

            while ((c = reader.read()) != -1) {
                sb.append((char) c);
            }
        }

        int statusCode = urlConnection.getResponseCode();
        if (statusCode < 200 || statusCode >= 300) {

        } else
            result = sb.toString();

    } catch (IOException e) {
        LOGGER.warning(e.getMessage());
    } finally {
        if (disconnect && urlConnection != null) {
            urlConnection.disconnect();
        }
    }

    return result;
}

Explicit questions to answer: How to log/trace/debug information used for authentication purpose on the client side? Any hint would be appreciated :)

Miki
  • 2,493
  • 2
  • 27
  • 39

3 Answers3

1

As far as I am aware, vanilla JDKs themselves do not have built-in NTLM support. This would then mean that you have to manually wire the steps of the protocol yourself.

I am writing this based on my experience: I had to roll a whole multi-round SPNEGO myself, which supports Oracle and IBM JRE. Was (not) fun. Although, that was just the server-side of the fun, I remember stumbling into this feature missing on Java-client side too (because it was SPNEGO and not plain NTLM, the client side was a browser, so I could skip that part).

This may have changed with the new HTTP Client in Java 11, I do not have any experience with that yet.

D. Kovács
  • 1,232
  • 13
  • 25
  • Thank you D. Kovacs for your contribution. Right now it is for sure that there was problem with JVM version. We figured this out in the process and ocde is now running in the same JRE on both environments. However I am trying to find out the way to figure this out without installing multiple JREs in try&fail pattern – Miki Jul 15 '19 at 11:35
1

Apache HttpClient in it's newer versions supports native Windows Negotiate, Kerberos and NTLM via SSPI through JNA when running on Windows OS. So if you have the option to use the newer version (from 4.4 I believe), this is a non-issue.

For example: http://hc.apache.org/httpcomponents-client-4.4.x/httpclient-win/examples/org/apache/http/examples/client/win/ClientWinAuth.java

Lista
  • 2,186
  • 1
  • 15
  • 18
-1

In order to debug your authentication exchange, you can add command line parameter :

-Djavax.net.debug=ssl,handshake.

This way, you'll have for both client step by step in handshake process.

Grunnpi
  • 92
  • 6
  • Great, I'll try it out as soon as I can! Thx! – Miki Jul 15 '19 at 14:27
  • Did you have a change to test ? – Grunnpi Jul 19 '19 at 11:33
  • sorry, but you've missed the whole point. According to javadocs javax.net.security package contains classes used for TLS/SSL connections. Questions doesn't refer to this type of connections – Miki Jul 22 '19 at 08:02