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]