As a part of the Android project I just started, I need to access a service secured by NTLM. On Windows Mobile this is handled automatically by WebClient. For iPhone I had to make the move from the more modern and high level UrlConnection / UrlRequest API to the old school non object oriented C style CFNetwork API. Android turns out to be a bit of the same story as with the iPhone. I started out with HttpURLConnection, only to disappointed again and redirected to the Apache HttpClient. But unlike CFNetwork on iPhone, HttpClient actually does not support NTLM “out of the box”…
According to the Apache Http Components documentation, this is due to two concerns; Microsoft only just made public the specification for NTLM in February 2008 and for whatever reason it is still not clear whether parts of the protocol are protected by patents. Secondly JCIFS is licensed under the Lesser General Public License and so is not necessarily compatible with the Apache License.
So instead of providing an actual implementation, we get a set of interfaces for clients to provide this functionality them self’s:
So how do these classes go together? The HttpClient needs an AuthScemeFactory that will return the AuthScheme descendant NTLMScheme. NTLMScheme requires an implementation of the NTLMEngine interface to operate on. The JCIFS library has functionality for creating type 1 2 & 3 NTLM messages making it a perfect candidate for implementing the NTLMEngine.
Source for the factory and engine and the code for registering the factory with HttpClient is here:
JCIFS can be had here:
I just imported the JCIFS library, straight copy-pasted the example code and haven’t looked back since.
Update: I just stumbled upon this page:
describing how the JCIFS NTLM implementation can be applied to HttpURLConnection – I haven’t tested it, so I don’t know if it will work with Android..
One detail i forgot: to start with i kept getting “Bad Request (Invalid Verb)”. It turned out that this is due to HttpClient sending EXPECT_CONTINUE as standard. This line disables that: