How to provide ntlm authentication while calling any url?
I have a hosted url which authenticates using ntlm (windows Integrated authentication). I am on windows and using java 1.8
URL url = new URL("someUrl");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
// con.setInstanceFollowRedirects(false);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// read response
...
in.close();
}else{
System.out.println("Error while fetching reponse, recieved response code " + responseCode);
}
The above code used to work till java 1.8.0_181 With subsequent updates it started failing, I have tested with 191 and 201. The code still works if backported to 181. I also tried using Authenticator, but it is not invoked (not sure why) With java's internal logging I could see following message in the logs "NegotiateAuthentication: java.io.IOException: Negotiate support not initiated" And I get 401
I am expecting any mechanism to help java negotiate on its own for authentication.
In Java release notes it is not mentioned anywhere but there is a change in NTLM authentication implementation. I have debugged the java code and arrived at following In java.home/lib there is file net.properties which now mentions following
#
# Transparent NTLM HTTP authentication mode on Windows. Transparent authentication
# can be used for the NTLM scheme, where the security credentials based on the
# currently logged in user's name and password can be obtained directly from the
# operating system, without prompting the user. This property has three possible
# values which regulate the behavior as shown below. Other unrecognized values
# are handled the same as 'disabled'. Note, that NTLM is not considered to be a
# strongly secure authentication scheme and care should be taken before enabling
# this mechanism.
#
# Transparent authentication never used.
#jdk.http.ntlm.transparentAuth=disabled
#
# Enabled for all hosts.
#jdk.http.ntlm.transparentAuth=allHosts
#
# Enabled for hosts that are trusted in Windows Internet settings
#jdk.http.ntlm.transparentAuth=trustedHosts
#
jdk.http.ntlm.transparentAuth=disabled
Till jdk1.8.0_181 there was a default NTLM authentication callback which was useful in NTLM authentication process.
To run the above code with jdk1.8.0_181 onward, all you need is to set jdk.http.ntlm.transparentAuth for your java process.
Alternatively, you may set a JVM argument, e.g., -Djdk.http.ntlm.transparentAuth=allHosts
, or set a system property, e.g., System.setProperty("jdk.http.ntlm.transparentAuth", "allHosts")
.
If you choose trustedHosts, make sure the URL is added in windows trusted site.
You can see this new system property used here during static init: sun.net.www.protocol.http.ntlm.NTLMAuthentication
.
Further, you can see the setting is used here: public static boolean NTLMAuthentication.isTrustedSite(URL)
Finally, to programmatically control if a URL is trusted, you may install a callback. See: sun.net.www.protocol.http.ntlm.NTLMAuthenticationCallback