This discussion is archived
2 Replies Latest reply: Mar 1, 2013 8:24 AM by jtahlborn RSS

Java 7 URLConnection error with ntlm authentication on Linux

994067 Newbie
Currently Being Moderated
Hi, I am trying to use a URLConnection to connection from a linux box with java 7 (64bit), to a windows web server which uses the NTLM authentication scheme.

My problem is that the following code worked with java 6 but doesn't work anymore in java 7 in linux (RHEL 6.4).
What makes it even more strange, is that if I run the exact same test program in windows with the java 7 that didn't work in linux, it works.

When it fails, I get the following exception :
java.net.ProtocolException: Server redirected too many times (20)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1637)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at TestWs.testWs(TestWs.java:68)
at TestWs.main(TestWs.java:21)

Java tries to authenticate to the server 20 times, it fails every time with error 401 and then throws the exception.

I was also able to access the url with the wget linux tool by using the same username and password from the same linux box, so network access, and the validity of the username/password are not in question. I run the exact same code but as soon as I switch the VM from java 6 to java 7, it stops working. I've also tried recompiling the class in java 7 or keeping the java 6 compiled class and use it in java 7, same result.

Here is the source code (url, password and username excluded...)


package com.test;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.URLConnection;

public class TestWs {

public static void main(String[] args) throws Exception {
new TestWs().testWs();
}

public void testWs() {
try {
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
Authenticator.setDefault(new MyAuthenticator("username", "password"));

URL url = new URL("https://someurlprotectedbyntlmauthentication.com");
URLConnection connection = url.openConnection();
InputStream is = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while (true) {
String s = br.readLine();
if (s == null)
break;
System.out.println(s);
}
System.out.println("Done");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

class MyAuthenticator extends Authenticator {
private String httpUsername;
private String httpPassword;

public MyAuthenticator(String httpUsername, String httpPassword) {
this.httpUsername = httpUsername;
this.httpPassword = httpPassword;
}

@Override
protected PasswordAuthentication getPasswordAuthentication() {
System.out.println("Scheme:" + getRequestingScheme());
return new PasswordAuthentication(httpUsername, httpPassword.toCharArray());
}
}

I'm thinking about submiting a java bug but I would like to explore every possible solutions before doing that.

Thanks for your help.
  • 1. Re: Java 7 URLConnection error with ntlm authentication on Linux
    994067 Newbie
    Currently Being Moderated
    After some more investigation, I found that the authentication works if I use a domain user, but not if I use a local user.

    This code from the JDK 7 causes me troubles (class com.sun.security.ntlm.Client) :

    public byte[] type3(byte[] type2, byte[] nonce) throws NTLMException {
    if (type2 == null || (v != Version.NTLM && nonce == null)) {
    throw new NullPointerException("type2 and nonce cannot be null");
    }
    debug("NTLM Client: Type 2 received\n");
    debug(type2);
    Reader r = new Reader(type2);
    byte[] challenge = r.readBytes(24, 8);
    int inputFlags = r.readInt(20);
    boolean unicode = (inputFlags & 1) == 1;
    String domainFromServer = r.readSecurityBuffer(12, unicode);
    *if (domainFromServer != null) {*
    domain = domainFromServer;
    *}*

    So, since the server is enroled in a domain, it sends back to the client it's domain as part of the NTLM protocol. Java replaces the domain that I'm trying to force by the variable "domainFromServer" everytime and it fails since the user exists on the server and not on the server's domain.

    I don't know exactly what to do with that.
  • 2. Re: Java 7 URLConnection error with ntlm authentication on Linux
    jtahlborn Expert
    Currently Being Moderated
    cross posted here:

    http://stackoverflow.com/questions/15124019/java-urlconnection-error-with-ntlm-authentication-but-only-on-linux-and-only-ja

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points