Dear HttpClient Support List,

I found out that when trying to make NTLM Authentication using 
httpclient-win-4.5.6.jar library it relies on CurrentWindowsCredentials instead 
of using credentials provided in WindowsCredentialsProvider which it seems to 
be incorrect for the case when web-container (Tomcat in my case) is running as 
a service under another "Local System" user on Windows machine. It retrieves 
incorrect username which is not authorized to pass NTLM authentication and gets 
401 Unauthorized Error. Besides, if web container (Tomcat in my case) is 
running inside Docker Linux Container it does not work at all because the user 
specified inside Docker Container is completely different from the Windows one. 
I suppose that in WindowsNegotiateScheme.authenticate() method the below 
implementation should not rely on CurrentWindowsCredentials and throw Exception 
but have to use the Credentials specified in WindowsCredentialsProvider.

if (clientCred == null) {
            // ?? We don't use the credentials, should we allow anything?
            if (!(credentials instanceof CurrentWindowsCredentials)) {
                throw new InvalidCredentialsException(
                        "Credentials cannot be used for " + getSchemeName() + " 
authentication: "
                                + credentials.getClass().getName());
            }

Also WindowsCredentialsProvider should not use instance of 
CurrentWindowsCredentials in case of AuthSchemes.NTLM but use 
provider.getCredentials(authscope) one:

public Credentials getCredentials(final AuthScope authscope) {
        final String scheme = authscope.getScheme();
        if (AuthSchemes.NTLM.equalsIgnoreCase(scheme) || 
AuthSchemes.SPNEGO.equalsIgnoreCase(scheme)) {
            return CurrentWindowsCredentials.INSTANCE;
        } else {
            return provider.getCredentials(authscope);
        }
    }

Besides, if user provides the credentials of another user which is different 
from the user logged in to Windows system, httpclient-win API should not try to 
get information about currently logged user via CurrentWindowsCredentials class 
but has to use those credentials provided in WindowsCredentialsProvider if 
there are provided. If the credentials are not provided, then probably makes 
sense to get user using CurrentWindowsCredentials.

Here is the code snippet how NTLM authentication was used in my case via 
httpclient-4.4.0.jar and httpclient-win-4.5.6.jar libraries:

HttpClientBuilder clientbuilder = HttpClients.custom();
Registry<AuthSchemeProvider> authSchemeRegistry = 
RegistryBuilder.<AuthSchemeProvider>create()
        .register(AuthSchemes.NTLM, new WindowsNTLMSchemeFactory(null))
        .build();
CredentialsProvider windowsCredentialsProvider = new 
WindowsCredentialsProvider(new SystemDefaultCredentialsProvider());
windowsCredentialsProvider.setCredentials(AuthScope.ANY, new 
NTCredentials("username, "password", "workstation", "domain"));
clientbuilder.setDefaultCredentialsProvider(windowsCredentialsProvider);
clientbuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);

RequestConfig.Builder requestBuilder = RequestConfig.custom();
requestBuilder = requestBuilder.setConnectTimeout(connectionTimeout);
requestBuilder = requestBuilder.setConnectionRequestTimeout(connectionTimeout);
clientbuilder.setDefaultRequestConfig(requestBuilder.build());
client = clientbuilder.build();

HttpGet get = new HttpGet("http://test.url/ntlm";);
CloseableHttpResponse  response = client.execute(get);

Could you please advise a workaround for the issue and make the corresponding 
fix if you consider my description as an issue?

Best regards,

www.jedox.com
Kirill Rajbhandary
Senior Software Engineer
+49 761 15147 237
Jedox AG
Bismarckallee 7a
79098Freiburg im Breisgau
Germany
Executive Board: Florian Winterstein (Chairman), Bernd Eisenblätter, Maximilian 
Prinz zu Hohenlohe-Waldenburg
​Supervisory Board: Bernhard Wöbker (Chairman), Curt Gunsenheimer, Thilo Schmid
​Place of Business: Amtsgericht Freiburg HRB 702118
​
​​[TM.V06112018]

Reply via email to