Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 694
Abhijeet Patil Avatar asked Feb 07 '19 07:02

Abhijeet Patil


People also ask

How do I set up NTLM authentication?

Click down to “Local Computer Policy -> Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> Security Options. Find the policy “Network Security: LAN Manager authentication level”. Right click on this policy and choose “Properties”. Choose “Send NTLMv2 response only/refuse LM & NTLM”.

How does NTLM over HTTP work?

NTLM uses Windows credentials to transform the challenge data instead of the unencoded user name and password. NTLM authentication requires multiple exchanges between the client and server. The server and any intervening proxies must support persistent connections to successfully complete the authentication.

How do I know if NTLM is authentication is enabled?

In the Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> Security Options section, find and enable the Network Security: Restrict NTLM: Audit NTLM authentication in this domain policy and set its value to Enable all.

What authentication method does NTLM use?

NTLM uses an encrypted challenge/response protocol to authenticate a user without sending the user's password over the wire. Instead, the system requesting authentication must perform a calculation that proves it has access to the secured NTLM credentials.


1 Answers

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

like image 154
Abhijeet Patil Avatar answered Sep 18 '22 12:09

Abhijeet Patil