Skip to content

Using HttpComponentsMessageSender with NTLM Authentication [SWS-964] #1035

Closed
@gregturn

Description

@gregturn

Sebastian Geiger opened SWS-964 and commented

I am trying to configure the HttpComponentsMessageSender for use with the WebServiceGatewaySupport implementation. My webservices use NTLM for authentication, so I need to configure that in the HttpClient which is being used by the message sender. This should be platform independent so I cannot just rely on the native windows fallback that the httpcommons library seems to include because that won't work under linux.

The Spring WS documentation seems to have no mention of either NTLM or configuring the HttpClient which is being used by the message sender. I understand that most of the API is actually from httpcomponents rather then Spring specific, but once a custom HttpClient is used certain methods on the HttpComponentsMessageSender cannot be used anymore. For example the setConnectionTimeout method. At least in this respect it would be nice if that was documented.

When I started to write this issue I was struggling to come up with a valid implementation to configure the HttpClient, but in the mean time I have figured it out. I still though I would post this issue, maybe the code can be useful to anyone how has the same problem or for improving the documentation.

This is what I came up with in the end:

    HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender ();

    AuthScope authscope;
    NTCredentials credentials;
    CredentialsProvider credentialsProvider;
    Registry<AuthSchemeProvider> registry;
    RequestConfig requestConfig;

    authscope = new AuthScope (HOST_IP, HOST_PORT);

    credentials = new NTCredentials ("user", "pass", null, "domain");

    credentialsProvider = new BasicCredentialsProvider ();

    credentialsProvider.setCredentials (authscope, credentials);

    registry = RegistryBuilder.<AuthSchemeProvider>create ()
            .register(AuthSchemes.NTLM, new NTLMSchemeFactory ())
            .build ();

    HttpRequestInterceptor interceptor
            = (request, context) -> request.removeHeaders(HTTP.CONTENT_LEN);

    requestConfig = RequestConfig.custom ()
                                 .setConnectTimeout (3000)
                                 .build ();

    HttpClient httpClient =  HttpClientBuilder.create ()
                                              .setDefaultRequestConfig (requestConfig)
                                              .setDefaultAuthSchemeRegistry (registry)
                                              .setDefaultCredentialsProvider (credentialsProvider)
                                              .addInterceptorFirst (interceptor)
                                              .build ();

    messageSender.setHttpClient (httpClient);

Points to pay attention to:

  1. The HttpRequestInterceptor is required or there will be a dubious error about a duplicate Content-Lenght header.
  2. Things like timeouts must be set in the RequestConfig and injected into the HttpClientBuilder, setting them directly on the HttpComponentsMessageSender causes an UnsupportedMethodException.
  3. It seems to be always necessary to pass the domain name to the NTCredentials class, before I was using the java.net native method and it was enough to just pass username and password to the Authenticator interface.

No further details from SWS-964

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions