How to set NTLM authentication in rest template Header in Spring - spring

I want to authenticate NTLM using Rest template , can any one suggest the way ?

If anyone stumble upon this entry again, this is the builtin solution:
Ensure your project includes the org.apache.httpcomponents.httpclient.
Then you can build your RestTemplate with this snippet:
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new NTCredentials(user, password, "source-host-name", "domain-name"));
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);

this is what I did taking cues from here. Credits goes here only.
Set up rest template to use apache http client -> compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.5'
Updated my rest template bean to use httpclient -
RestTemplate restTemplate = new RestTemplate();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
restTemplate.setRequestFactory(requestFactory);
Then just do what the link here says. Add the NtlmAuthenticator class and do this just before your restTemplate call.
NtlmAuthenticator authenticator = new NtlmAuthenticator(userName, password);
Authenticator.setDefault(authenticator);
That's it. You are all set up.

Related

springboot 3.0 restTemplate with SSLHostNameVerifier

We are upgrading to springboot 3.0 and we have the following resttemplate code.The following code creating issue at CloseableHttpClient and NoopHostnameVerifier.We are upgrading this app to springboot 3.0.
`
#Bean public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()) .build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory( httpClient);
restTemplate.setRequestFactory(clientHttpRequestFactory);
return restTemplate;
}
`
We are noware found NoopHostnameVerifier,CloseableHttpClient.Any help is appreciated.
Upgrade to spring boot 3
Thanks in Advance

Adding Java environment variables in application.properties in springboot

I am running a springboot application which requires to trust the certificate which i added in my local truststore.
For now i am setting it under run configurations options in intellij and it works.
ex->::-Djavax.net.ssl.trustStore=location\cacerts;-Djavax.net.ssl.trustStorePassword=changeit
I was wondering is there any way to set it from application.properties file in springboot in the way we set spring properties?
If you want to make REST calls, You can configure the RestTemplate Bean like :
#Configuration
public class SslConfiguration {
#Value("${http.client.ssl.trust-store}")
private Resource keyStore;
#Value("${http.client.ssl.trust-store-password}")
private String keyStorePassword;
#Bean
RestTemplate restTemplate() throws Exception {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(
keyStore.getURL(),
keyStorePassword.toCharArray()
).build();
SSLConnectionSocketFactory socketFactory =
new SSLConnectionSocketFactory(sslContext);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory).build();
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
}
Check this : Example

Verify Certificate and Hostname for an HTTPS REST call with Spring RestTemplate

I have a Spring Boot Microservice where I am trying to invoke an external server which exposes an HTTPS REST Endpoint (TLS v1.2). I have been provided the server side certificate in .pem format.
I would like to implement this call using RestTemplate and use the provided certificate and verify the host name during the call.
I have tried to Google this and all the search results are trying to ignore the certificate and host name.
Can I have an example code snippet to implement this properly?
After some digging with different blogs and stackoverflow threads, following worked for me:
Create Rest Template:
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(ResourceUtils.getFile(clientKeyPath)), "".toCharArray());
SSLContext sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(keyStore, null)
.loadTrustMaterial(ResourceUtils.getFile(keystorePath), keystorePassword.toCharArray())
.build();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new CustomHostnameVerifier());
HttpClient client = HttpClients
.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(client);
RestTemplate sslRestTemplate = new RestTemplate(requestFactory);
Implementation of CustomHostnameVerifier:
#Component
public class CustomHostnameVerifier implements HostnameVerifier {
#Value("${dns.name}")
private String dnsName;
#Override
public boolean verify(String hostname, SSLSession session) {
return hostname.equals(dnsName);
}
}

SpringBoot RestTemplate Connection Pooling: Managing Stale Connections

I am using RestTemplate with ConnectionPooling using PoolingHttpClientConnectionManager as in below code :
PoolingHttpClientConnectionManager connectionManager = new
PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS);
connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
connectionManager.setMaxPerRoute(new HttpRoute(new
HttpHost(excConfig.getImsServerEndpoint())), IMS_ROUTE_MAX_CONNECTIONS);
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connectionManager).build();
HttpComponentsClientHttpRequestFactory httpReqFactory = new HttpComponentsClientHttpRequestFactory(httpclient);
httpReqFactory.setReadTimeout(DEFAULT_HTTP_TIMEOUT_MILLISECONDS);
httpReqFactory.setConnectionRequestTimeout(DEFAULT_HTTP_TIMEOUT_MILLISECONDS);
httpReqFactory.setConnectTimeout(DEFAULT_HTTP_TIMEOUT_MILLISECONDS);
restTemplate = new RestTemplate(httpReqFactory);
Does RestTemplate take care of terminating stale connections by itself? Or do I need to put in some specific handling for the same?
By default it does not, but you can configure it easily in your CloseableHttpClient configuration.
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true))
.setConnectionManager(connectionManager)
.build();`
Source here.
setStaleConnectionCheckEnabled has become obsolete.
HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true))
.setConnectionManager(connectionManager)
.build();
In HttpClient 4.5.3 the below code works -
PoolingHttpClientConnectionManager connManager
= new PoolingHttpClientConnectionManager();
connManager.setValidateAfterInactivity(20);
HttpClient httpClient = HttpClients.custom().setConnectionManager(connManager).build();

How do I set timeouts per request using Spring REST Template?

I have an application that makes use of multiple rest clients. Each of those REST clients use the same Spring REST template bean. I was wondering if there was a way to set the timeout value per request using the Spring rest template?
This worked for me...
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
private ClientHttpRequestFactory getClientHttpRequestFactory() {
int timeout = 5000;
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory
= new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setConnectTimeout(timeout);
return clientHttpRequestFactory;
}
To achieve calling rest template with timeout, first you should create config class also use with #Bean annotation, then implement in class and call with RestTemplateConfig.
#Configuration
public class RestTemplateConfig {
#Bean
public RestTemplate restTemplate() {
return new RestTemplate(clientHttpRequestFactory());
}
private ClientHttpRequestFactory clientHttpRequestFactory() {
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setConnectionRequestTimeout(4000);
clientHttpRequestFactory.setReadTimeout(4000);
clientHttpRequestFactory.setConnectTimeout(4000);
return clientHttpRequestFactory;
}
}
But I suggest you use Apache HttpClient, you can manage the connection pool, keep-alive, idle monitor and also create custom error handler. You can check the link: https://springframework.guru/using-resttemplate-with-apaches-httpclient/
You can also modify the SimpleClientHttpRequestFactory.
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(customHttpRequestFactory());
private SimpleClientHttpRequestFactory customHttpRequestFactory() {
SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
simpleClientHttpRequestFactory.setReadTimeout(2000);
simpleClientHttpRequestFactory.setConnectTimeout(2000);
return simpleClientHttpRequestFactory;
}

Resources