This is my client setup
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("keystore");
sslContextFactory.setKeyStorePassword("blah");
HttpClient httpClient = new HttpClient(sslContextFactory);
and this is my how I get the request object.
Request request = client.newRequest(host, port);
How do I send the request as https?
thanks
The answer is
request.scheme(HttpScheme.HTTPS.toString()):
that is all
Related
I'm building an application that need to call an endpoint using NTLM authentication. My approach is that I try to use the Apache HttpComponents for the NTLM authentication and integrate the Spring WebClient with it. However, the WebClient doesn't seem to send any request at all. There's no errors but the response won't be returned.
Below is my code:
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(null, -1), new NTCredentials(username, password, computername, domain));
HttpAsyncClientBuilder clientBuilder = HttpAsyncClients.custom();
clientBuilder.setDefaultRequestConfig(RequestConfig.DEFAULT);
ClientHttpConnector connector = new HttpComponentsClientHttpConnector(client);
WebClient.builder().clientConnector(connector).build();
ResponseDto response = webClient.post()
.uri("http://myhost:8080/api/notification/add")
.body(Mono.just(request), RequestDto.class)
.retrieve()
.bodyToMono(ResponseDto.class).block();
I'm trying to setup a WebClient connection in Spring Boot using a proxy. My implementation looks like the following:
final WebClient.Builder webclientBuilder = WebClient.builder();
final HttpClient httpClient = HttpClient.create();
httpClient.proxy(proxy -> proxy
.type(Proxy.HTTP)
.host(proxyName)
.port(Integer.parseInt(proxyPort)));
final ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
webclientBuilder.clientConnector(connector);
final WebClient webClient = webclientBuilder
.baseUrl(baseUrl)
.build();
After running it and sending an API call, I receive a "Connection timed out: no further information". I should get back a Bad Request (in case my call is wrong), but I don't.
Is the implementation wrong?
the proxyName is written like this: "proxy.blabla.de"
After some trial and error and comparing I found a solution working for me:
String baseUrl = "https://mybaseurl";
String proxyName = "proxy.blabla.de";
int proxyPort = 1234;
public InitResponse addAccount() {
// for logging purposes, nothing to do with the proxy
LOGGER.info("LOGGER.info: addAccount()");
final InitRequest request = buildRequest();
HttpClient httpClient = HttpClient.create()
.proxy(proxy -> proxy.type(Proxy.HTTP)
.host(proxyName)
.port(proxyPort));
ReactorClientHttpConnector conn = new ReactorClientHttpConnector(httpClient);
WebClient webClient = WebClient.builder().clientConnector(conn).baseUrl(baseUrl).build();
I am building an application that reads JSON response from certain endpoints and I am trying to authenticate in Apache HttpClient using NTLM authentication:
The class that is responsible for authentication HttpConnector tries to authentice right after its instantiation:
public static HttpConnector on(String username, String password) {
HttpConnector connector = new HttpConnector(username, password);
Credentials credentials = new NTCredentials(username, password, "host", "domain");
connector.getHttpClient().getState().setCredentials(AuthScope.ANY, credentials);
return connector;
}
but I always get response code 401 Unauthorized. As I read in internet including here in Stackoverflow I used NTCredentials that I am trying to set globally in the HttpClient. I have tested the endpoints in Postman, there I get the JSON response successfully but HttpClient cannot connect.
In the code I use GetMethod: httpMethod = new GetMethod(url);
Here I have also tried to configure authentication but it still does not work:
private void configureMethod(HttpMethod httpMethod) throws MalformedChallengeException {
httpMethod.getHostAuthState().setAuthRequested(true);
httpMethod.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
httpMethod.setDoAuthentication(true);
httpMethod.getParams().setParameter(
HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
httpMethod.getHostAuthState().setAuthRequested(true);
httpMethod.getHostAuthState().setAuthScheme(
new NTLMScheme(
String.format("ntlm %s:%s", username, password)));
}
During debugging I see that I get: Connection reset by peer: socket write error. It happens in HttpMethodDirector::executeWithRetry(final HttpMethod method) method.
Can someone help me, what is the correctNTLM authentication setup in Apache HttpClient. Can I really use the global set of credentials or I have to setup credentials to every HttpMethod I create and how?
Thank you in advance!
I fixed this by formatting the client the following way:
HttpClient httpClient = new DefaultHttpClient();
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
new NTCredentials(username, password, HOST, MY_DOMAIN));
And the used not GetMethod but HttpGet:
HttpGet = getRequest = new HttpGet(url);
and this time the connection owas successful.
I have a RestTemplate call to an API (get). This call, is the only we have of GET type, and go through a proxy. It seems that sometimes during a week, the call returns a 403 Forbidden with this exception: "sun.security.validator.ValidatorException"
We have a certificate between Spring and the API, but the certificate works fine (the application returns thousands of "200 ok" during a day).
But sometimes, only this call (not others that are POST) returns a "403 Forbidden".
We have done:
Launch Jmeter with curl through the proxy (everything seems ok)
Disable the TrustStore only to test (the result is ko)
This is the RestTemplate code:
SSLConnectionSocketFactory socketFactory;
socketFactory = new SSLConnectionSocketFactory(new SSLContextBuilder()
.loadTrustMaterial(ResourceUtils.getFile(this.trustStorePath), this.trustStorePassword.toCharArray())
.loadKeyMaterial(ResourceUtils.getFile(this.keyStorePath), this.keystorePassword.toCharArray(),
this.keystorePassword.toCharArray())
.build(), NoopHostnameVerifier.INSTANCE);
CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(socketFactory).setProxy(host)
.disableCookieManagement().disableRedirectHandling().build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(client);
RestTemplate restTemplateVar = new RestTemplate(requestFactory);
And this is the call:
response = this.restTemplate.getForEntity(this.host, String.class);
Could the number of concurrent connections be the cause?
Why only with GET and sometimes?
And the last one: If we change RestTemplate by Httpconnection, the result could be different?
Thank in advance
Setting this properties works fine (it depends on your metrics)
.setMaxConnTotal(1000)
.setMaxConnPerRoute(40)
CloseableHttpClient client = HttpClients.custom()
.setSSLSocketFactory(socketFactory)
.setProxy(host)
.disableCookieManagement()
.disableRedirectHandling()
.setMaxConnTotal(1000)
.setMaxConnPerRoute(40)
.build();
My development environment is behind a proxy so i need to set the proxy information to the rest template, that's all good when i use a HttpComponentsClientHttpRequestFactory and set the proxy setting in the httpClient and set it in the template.
But now i have a rest service that needs basic auth. And to set the basic auth credentials, i need to set them in the httpClient on the rest template. But i see that the getparams method in the httpClient is depricated, so i can't just update the existing client in the template, and if i create a new httpclient object, i will overwrite the proxy info that were set during the application bootstrapping.
So is there some way that i could extract the httpClient from the rest template and update it? Or is there any other way to tackle this?
Thanks.
Configure the httpClient as follows:
HttpHost target = new HttpHost("hostname", 80, "http");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials("user", "passwd"));
HttpHost proxy = new HttpHost("proxy", 12345);
CloseableHttpClient httpclient = HttpClients.custom()
.setProxy(proxy)
.setDefaultCredentialsProvider(credsProvider).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpclient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
See also HttpClient Examples
The above solution did not work for me i work around the above and finally make it work with small modifications.
RestTemplate restTemplate = new RestTemplate();
HttpHost proxy =null;
RequestConfig config=null;
String credentials = this.env.getProperty("uname") + ":" + this.env.getProperty("pwd");
String encodedAuthorization = Base64.getEncoder().encodeToString(credentials.getBytes());
Header header = new BasicHeader(HttpHeaders.AUTHORIZATION, "Basic " + encodedAuthorization);
List<Header> headers = new ArrayList<>();
headers.add(header);
if(Boolean.valueOf(env.getProperty("proxyFlag"))){
proxy = new HttpHost(this.env.getProperty("proxyHost"), Integer.parseInt(env.getProperty("proxyPort")), "http");
config= RequestConfig.custom().setProxy(proxy).build();
}else{
config= RequestConfig.custom().build();
}
CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config)
.setDefaultHeaders(headers).build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplate.setRequestFactory(factory);
return restTemplate;