This is basically an all-in-one repository for techie developer-related things I've experienced / come-across and from where I can easily look-up later.
From small useful tidbits, code / key shortcuts, tips, to articles /guides on how to do certain complicated tasks, all the way to full mini-programs for daily use.
If it helps anyone else out too great!

Wednesday, May 12, 2010

Here, I'll explain how to get NTLMv2 support in HttpClient 3.x using JCIFS by using 1 addditional class and inserting 1 new line into your existing calls to HttpClient.Of course you can use JCIFS NTLM authentication directly in Java even if you don't have Apache HttpClient - I'm not looking at that but you can refer to this guide on JCIFS home page.

HttpClient

Apache's HttpClient provides some useful encapsulation for fetching/posting data over HTTP through Java code. The common version is HttpClient 3.x whereas the latest version is HttpClient 4.x.

NTLM

One of HttpClient's advantages is that it has built in support to manage communications over an NTLM proxy.

NTLM is a very closely guarded Proxy protocol used by Microsoft but still popularly used.

JCIFS

Unfortunately, HttpClient does not have built in support for NTLM v2. The good news is, it allows you to integrate NTLMv2 support in another library called JCIFS.

JCIFS is an Open Source client library that implements the CIFS/SMB networking protocol in 100% Java. See more details/download from here. But since JCIFS started NTLMv2 support only from 1.3.0, make sure you have the latest JCIFS jar (I tested with JCIFS 1.3.14).

JCIFS in HttpClient

Thankfully, HttpClient 4.x home site has a page containing unofficial steps for integrating JCIFS into HTTPClient. However, these steps will only work for 4.x and not for for 3.x. This is because HttpClient 4.x is not backward compatible with 3.x. There are major changes like package structures, new Engines instead of States, etc.

Since I was using HttpClient 3.x, I started thinking of upgrading to 4.x – but it was obvious upgrading to 4.x from 3.x was a nightmare just to get NTLMv2 support.

Steps and source-code

Thankfully, it was just a matter of understanding HttpClient 3.x internal calls from the source. I was able to create 1 simple class that will do the integration in 1 smooth move.

1)I created a new class, JCIFS_NTLMScheme.java that would be used in place of HTTPClient's NTLMScheme.

This new class simply makes calls to JCIFS internally to generate NTLMv2's Type1, 2 and 3 messages- just reimplemented the methods with slight logic changes to generate the messages:

38 comments:

Hello and thanks for this useful post. I have implemented the code above using HTTPClient 3 and JCIFS, but I am getting a 500 HTTP error and a "The function requested is not supported" error msg from the server. Any ideas?

Hey Andy. I never came across this error but I have some suggestions...Guess you know that the HTTP error code as 500, stands for internal server error. In such a case, you should be able to get a full stack trace of the exception from the server too... If the error is on a browser like Internet Explorer, you can simply go to the advanced tab and uncheck the "Show friendly error" option - you should get the stack displayed in the browser next time you attempt the connection.If you aren't able to get a clue from the stack, post the stack back here.Also, could you show the code where you create NTCredentials and how you use them (star out any usernames and passwords of course :) )?I have some more ideas if that doesnt work either...

@AndyI got a similar error. The reason was that the LAN Manager Authentication Level in the Local Security Policy of the win2k machine that I was working on was set to "Send NTLMV2 response only, refuse LM and NTLM.."Also all the flags were enabled in the setting "Minimum session security for NTLM SSP ......"

If you relax the settings of LAN Manager Authentication level and disable the NTLM V2 flag in the session security settings things should work fine

I have a customer requirement in which they have mandated NTLMV2 only. The local policy settings on their Win2k server is

1. Send NTLMV2 response only, refuse LM and NTLM..2. Also all the flags were enabled in the setting "Minimum session security for NTLM SSP ......clients"3. Also all the flags were enabled in the setting "Minimum session security for NTLM SSP ......servers"

I tried out your code by creating a JCIFS_NTLMScheme class and registering it with Httpclient 3.x. as mentioned in your example above. I still get the error "The function requested is not supported".

Can you please tell me if I am missing something here. Does JCIFS work with the above security setting?

First of all, I didn't really have access to my Server details - so I have no clue about the policy settings. However, JCIFS is supposed to have full NTLMv2 support...

I think your problem is elsewhere - NTLMv2 support in JCIFS started only from JCIFS version 1.3.0 whereas it looks like you are using version 1.1.11. Make sure you have the latest JCIFS (I had done my testing with 1.3.14 - it worked flawlessly with NTLMv2 and I know my proxy server has full security on).

Another issue is that it you said you are using the JCIFS jar file only for compiling JCIFS_NTLMScheme.java. However, you have to ensure that the JCIFS jar file is available in the classpath at runtime as well.

I was getting 401: Unauthorised error so have been searching for solution and found your post. I implemented the code as per what is stated in the post but I still get 401:Unauthorised error. Any clue where to look?

This solution did not work for me.But I checked out a fork of the same library, with this or similar fix incorporated, built it (it produces EWSJavaAPI_1.2.2) and it worked great: https://github.com/casimirenslip/EWS-Java-API

Hi All,Thanks to Sachin that I am able to overcome the support issue with Axis 1.6.2 in my case. However I would like to share a key information that I have found with the JCIFS_NTLMScheme code. This code didnt work as is with an service hosted on IIS 7.5 with only NTLMv2 supported. After lot of troubleshooting and suggestion from my architect had to forcefully use the flag "NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2" in type1 and type3 message constructors instead of using default flags. Hope this will help who has a similar issue.

We are using the same code, we see that it is using the JCIFNTLMScheme, however, we still get a 401 - Credentials not provided in third handshake. We are not able to understand what is going wrong. Any pointers?

Hi Sachin,I have created stubs using WSIMPORT and followed the steps that you have mentioned in your post. But it didn't work for me and I am getting Authentication failure. Can you please help. Thanks