(I apologize for the delay in posting this update. It was delayed due to matters outside of my control. Nonetheless, I am sure that anyone struggling to gain NTLMv2 support with version 4.1.x will be helped by taking a look at the following:)
------------------------------------------------------------------------ I have tried JCIFS and was able to get all of my test cases to pass. But, it doesn't support NTLMv2 "out of the box" because its NegotiateFlags (see section 2.2.2.5 of the Microsoft's [MS-NLMP] spec) is insufficient. My implementation is based upon the example that used to be found at: http://hc.apache.org/httpcomponents-client/ntlm.html I was able to locate the info on the way-back machine at: http://replay.waybackmachine.org/20090611051135/http://hc.apache.org/httpcomponents-client/ntlm.html Since the built-in NTLM implementation is insufficient, the maintainers may wish to restore this page, with the slight adjustment that I found necessary, or with the following code, which I have verified works with both NTLMv1 and NTLMv2 authentication: ------------------------------------------------------------------------ import java.io.IOException; import jcifs.ntlmssp.NtlmFlags; import jcifs.ntlmssp.Type1Message; import jcifs.ntlmssp.Type2Message; import jcifs.ntlmssp.Type3Message; import jcifs.util.Base64; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeFactory; import org.apache.http.client.params.AuthPolicy; import org.apache.http.impl.auth.NTLMEngine; import org.apache.http.impl.auth.NTLMEngineException; import org.apache.http.impl.auth.NTLMScheme; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpParams; public final class JCIFSEngine implements NTLMEngine { private static final int TYPE_1_FLAGS = NtlmFlags.NTLMSSP_NEGOTIATE_56 | NtlmFlags.NTLMSSP_NEGOTIATE_128 | NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2 | NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NtlmFlags.NTLMSSP_REQUEST_TARGET; public String generateType1Msg(final String domain, final String workstation) throws NTLMEngineException { final Type1Message type1Message = new Type1Message(TYPE_1_FLAGS, domain, workstation); return Base64.encode(type1Message.toByteArray()); } public String generateType3Msg(final String username, final String password, final String domain, final String workstation, final String challenge) throws NTLMEngineException { Type2Message type2Message; try { type2Message = new Type2Message(Base64.decode(challenge)); } catch (final IOException exception) { throw new NTLMEngineException("Invalid NTLM type 2 message", exception); } final int type2Flags = type2Message.getFlags(); final int type3Flags = type2Flags & (0xffffffff ^ ( NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER)); final Type3Message type3Message = new Type3Message(type2Message, password, domain, username, workstation, type3Flags); return Base64.encode(type3Message.toByteArray()); } public static void register(final DefaultHttpClient httpClient) { httpClient.getAuthSchemes().register(AuthPolicy.NTLM, new AuthSchemeFactory() { public AuthScheme newInstance(final HttpParams httpParams) { return new NTLMScheme(new JCIFSEngine()); } }); } } ------------------------------------------------------------------------ Then, just insert a call to JCIFSEngine.register() for each newly created DefaultHttpClient instance. -----Original Message----- From: Oleg Kalnichevski [mailto:[email protected]] Sent: Friday, March 11, 2011 10:07 AM To: HttpClient User Discussion Subject: Re: NTLM authentication with a UPN instead of domain and user name On Fri, 2011-03-11 at 17:47 +0000, Ron Jacobs wrote: > I am using NTLM authentication and I find that when porting from 3.0.2 > to 4.1, I have several questions: > > 1) Authenticating with domain and user works but with a UPN (like > "[email protected]") authentication fails although both authenticate > fine with my previous 3.0.2 code. Why does the UPN-style not work? > HttpClient 4.1 has a completely new NTML engine contributed by an external project. Apparently it does not work with UPN style user names. You may want to try out JCIFS based NTLM engine and see if it works better. > 2) How should I set credentials for NTLM where there is no domain, like > when using the UPN form? NTCredentials with domain "" or null, or > UsernamePasswordCredentials? I have tried various combinations > without success. > As far as I understand if it is a standalone workstation the domain should be same as the the workstation name. > 3) I am accessing a web service from outside the NT domain so I have no > workstation name for the 3rd parameter to the NTCredentials > constructor. I have tried passing null, "", or "somejunk" without > success. > Again, my knowledge of MS Windows networking is awfully outdated, but as far as I remember there is _always_ an authentication domain of some sort. In the simplest form the workstation can act as its own auth domain. Anyhow it has been ages since I touches anything called Windows > 4) The NTCredentials constructor seems happy to set workstation to null > but I find that when it is null a NullPointerException is thrown from > somewhere within your NTLM code. > Feel free to raise a JIRA for this defect. Oleg --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
