Spring boot using https only - Test failing - spring-boot

I have spring boot - angular application
My server port is 1234 (example).
But now I have setup ssl
Steps:
created self signed cert using keytool and added my p12 cert file into resources folder
updated application.properties
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:myfile.p12
server.ssl.key-store-password=somepasswordfromenv
server.ssl.key-alias=myalias
server.ssl.enabled=true
http.port=8080
server.port=8443
Started app and tested
#SpringBootTest(classes = AppWithoutBeansApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT)
class AppControllerTest {
#Value("${server.ssl.key-store}")
private Resource trustStore;
#Value("${server.ssl.key-store-password}")
private String trustStorePassword;
#Test
public void givenAcceptingAllCertificatesUsing4_4_whenUsingRestTemplate_thenCorrect()
throws ClientProtocolException, IOException {
String urlOverHttps = "https://localhost:8443/";
CloseableHttpClient httpClient
= HttpClients.custom()
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
HttpComponentsClientHttpRequestFactory requestFactory
= new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
ResponseEntity<String> response
= new RestTemplate(requestFactory).exchange(
urlOverHttps, HttpMethod.GET, null, String.class);
assertThat(response.getStatusCode().value(), equalTo(200));
}
...
Error:
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://localhost:8443/": Certificate for doesn't match any of the subject alternative names: []; nested exception is javax.net.ssl.SSLPeerUnverifiedException: Certificate for doesn't match any of the subject alternative names: []
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:746)
Don't understand how my integration test works

All answers looked similar, but this one worked
Ignore SSL certificate validation when using Spring RestTemplate
#Bean
public RestTemplate restTemplate() throws GeneralSecurityException {
TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslsf).register("http", new PlainConnectionSocketFactory()).build();
BasicHttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager(
socketFactoryRegistry);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
.setConnectionManager(connectionManager).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
Looks like this part made the difference
*Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslsf).register("http", new PlainConnectionSocketFactory()).build();*
DO NOT USE THIS
// #Bean
// public RestTemplate nonsslrestTemplate() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
// TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
// SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
// SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
// CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
// HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
// requestFactory.setHttpClient(httpClient);
// return new RestTemplate(requestFactory);
// }

Related

Configure SSL with Webflux Webclient using Apache HttpComponents

I am trying to migrate from restTemplate to webClient.
Everything was fine until I reached restTemplate config with ClientHttpRequestFactory.
I paste here the old and the new codes.
------Old code with restTemplate-------
private HttpComponentsClientHttpRequestFactory buildRequestFactory() {
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
HttpHost proxy = new HttpHost(proxyHost, proxyPort);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(proxyHost, proxyPort),
new UsernamePasswordCredentials(proxyUser, proxyPassword));
clientBuilder.useSystemProperties();
clientBuilder.setProxy(proxy);
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
};
SSLContext sslContext = null;
try {
sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
throw new ServiceException(GlobalErrorMessage.INTERNAL_SERVER_ERROR);
}
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
CloseableHttpClient httpClient = clientBuilder
.setSSLSocketFactory(connectionFactory)
.setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {
#Override
public HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context)
throws HttpException {
if (target.getHostName().equals(noproxy)) {
return null;
}
return super.determineProxy(target, request, context);
}
})
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return requestFactory;
}
#Bean(name = "gatewayRestTemplate")
public RestTemplate gatewayRestTemplateConfig() {
RestTemplate restTemplate = new RestTemplate(converters());
restTemplate.setRequestFactory(buildRequestFactory());
return restTemplate;
}
------New code with webClient-------
private ClientHttpConnector buildClientConnector() {
HttpAsyncClientBuilder clientBuilder = HttpAsyncClients.custom();
org.apache.hc.core5.http.HttpHost proxy = new org.apache.hc.core5.http.HttpHost(proxyHost, proxyPort);
org.apache.hc.client5.http.auth.CredentialsProvider credsProvider = new org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider();
((org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider) credsProvider).setCredentials(new org.apache.hc.client5.http.auth.AuthScope(proxyHost, proxyPort),
new org.apache.hc.client5.http.auth.UsernamePasswordCredentials(proxyUser, proxyPassword.toCharArray()));
clientBuilder.useSystemProperties();
clientBuilder.setProxy(proxy);
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new DefaultAuthenticationStrategy());
TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
};
SSLContext sslContext = null;
try {
sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
throw new ServiceException(GlobalErrorMessage.INTERNAL_SERVER_ERROR);
}
org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory connectionFactory =
new org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
org.apache.hc.core5.http.config.Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
// .<org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory>create().register("https", connectionFactory)
.<ConnectionSocketFactory>create().register("https", connectionFactory)
// .register("http", new PlainConnectionSocketFactory())
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpAsyncClient client = clientBuilder
.setConnectionManager((AsyncClientConnectionManager) connectionManager)
.setRoutePlanner(new org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner(proxy) {
#Override
protected org.apache.hc.core5.http.HttpHost determineProxy(org.apache.hc.core5.http.HttpHost target, org.apache.hc.core5.http.protocol.HttpContext context) throws org.apache.hc.core5.http.HttpException {
if (target.getHostName().equals(noproxy)) {
return null;
}
return super.determineProxy(target, context);
}
})
.build();
ClientHttpConnector connector = new HttpComponentsClientHttpConnector(client);
return connector;
}
#Primary
#Bean(name = "defaultWebClient")
public WebClient defaultWebClientConfig() {
WebClient webClient = WebClient.builder()
.clientConnector(buildClientConnector())
.build();
return webClient;
}
When I run the project, I get this exception:
Caused by: java.lang.ClassCastException: class org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager cannot be cast to class org.apache.hc.client5.http.nio.AsyncClientConnectionManager (org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager and org.apache.hc.client5.http.nio.AsyncClientConnectionManager are in unnamed module of loader 'app')
Based on Migration to Apache HttpClient 5.0 async APIs, I solved my problem. The idea is to use ClientTlsStrategyBuilder when setting sslContext.
private ClientHttpConnector buildClientConnector() {
HttpAsyncClientBuilder clientBuilder = HttpAsyncClients.custom();
org.apache.hc.core5.http.HttpHost proxy = new org.apache.hc.core5.http.HttpHost(proxyHost, proxyPort);
org.apache.hc.client5.http.auth.CredentialsProvider credsProvider = new org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider();
((org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider) credsProvider).setCredentials(new org.apache.hc.client5.http.auth.AuthScope(proxyHost, proxyPort),
new org.apache.hc.client5.http.auth.UsernamePasswordCredentials(proxyUser, proxyPassword.toCharArray()));
clientBuilder.useSystemProperties();
clientBuilder.setProxy(proxy);
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new DefaultAuthenticationStrategy());
TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;
SSLContext sslContext;
try {
sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
throw new ServiceException(GlobalErrorMessage.INTERNAL_SERVER_ERROR);
}
PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(ClientTlsStrategyBuilder.create()
.setSslContext(sslContext)
.setHostnameVerifier(new NoopHostnameVerifier())
.build())
.build();
CloseableHttpAsyncClient client = clientBuilder
.setConnectionManager(connectionManager)
.setRoutePlanner(new org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner(proxy) {
#Override
protected org.apache.hc.core5.http.HttpHost determineProxy(org.apache.hc.core5.http.HttpHost target, org.apache.hc.core5.http.protocol.HttpContext context) throws org.apache.hc.core5.http.HttpException {
if (target.getHostName().equals(noproxy)) {
return null;
}
return super.determineProxy(target, context);
}
})
.build();
ClientHttpConnector connector = new HttpComponentsClientHttpConnector(client);
return connector;
}
#Primary
#Bean(name = "defaultWebClient")
public WebClient defaultWebClientConfig() {
WebClient webClient = WebClient.builder()
.clientConnector(buildClientConnector())
.build();
return webClient;
}
If you want to use HttpClient connector. Please use below code for
webclient. The above answers any of them not worked, below solution is
working fine for me.
SslContext sslContext = SslContextBuilder
.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.build();
HttpClient httpClient = HttpClient.create().secure(t ->
t.sslContext(sslContext) );
WebClient webClient = WebClient.builder()
.baseUrl("any-url")
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();

Spring RestTemplate certificate 403 Forbidden: [no body]

I use p12 certificate with RestTemplate to call an external API.
RestTemplate:
final SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(keyStoreFile.getURL(), keyPassword.toCharArray(), (X509Certificate[] chain, String authType) -> true)
.build();
final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, INSTANCE);
final HttpClient httpClient = custom()
.setSSLSocketFactory(socketFactory)
.setMaxConnTotal(1000)
.setMaxConnPerRoute(40)
.build();
final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(requestFactory));
And the call:
HttpEntity<String> entity = new HttpEntity<>(httpHeaders);
final ResponseEntity<MyList> response = restTemplate.exchange("https://REMOTE_URI/sameObjects", GET, entity, MyList.class);
I tried header with differents values (User-Agent, Host, ..) and ResponseEntity<Object> , but I have always the same error :
org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden: [no body]
I can access it with Postman with the p12 certificate.
Thank you for your help
I found the solution, I change RestTemplate :
public RestTemplate getRestTemplate() {
try {
final KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(keyStoreFile.getInputStream(), keyPassword.toCharArray());
final SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(keyStoreFile.getURL(), keyPassword.toCharArray(), (X509Certificate[] chain, String authType) -> true)
.loadKeyMaterial(keyStore, keyPassword.toCharArray())
.build();
final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, INSTANCE);
final HttpClient httpClient = custom()
.setSSLSocketFactory(socketFactory)
.build();
final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(requestFactory));
return restTemplate;
} catch (IOException e) {
log.error("....", e);
throw new ApiException(e);
} catch (Exception e) {
log.error("....", e);
throw new ApiException(e);
}
}

Post resttemplate in Spring does not work and get works

This is my client code:
#GetMapping("/")
public String home() throws NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, KeyStoreException, KeyManagementException, UnrecoverableKeyException, RestClientException, URISyntaxException {
String url = "https://localhost:8483/secure-server/hola";
//
// KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
//
// keyStore.load(new FileInputStream(new File("client-keystore.jks")), "secret".toCharArray());
//
// System.out.println(url);
// SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
// new SSLContextBuilder()
// .loadTrustMaterial(null, new TrustSelfSignedStrategy())
// .loadKeyMaterial(keyStore, "secret".toCharArray())
// .build(),
// NoopHostnameVerifier.INSTANCE);
//
// HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
//
// ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
// RestTemplate restTemplate = new RestTemplate(requestFactory);
// String record = restTemplate.getForObject(url, String.class);
////
//
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<>("", headers);
return restTemplate.exchange(url, HttpMethod.POST, request , String.class ).getBody();
//
// ResponseEntity<String> resp = restTemplate.exchange(
// new URI(url), HttpMethod.GET,
// httpEntity, String.class);
//return model.getBody();
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception {
char[] password = "secret".toCharArray();
SSLContext sslContext = SSLContextBuilder.create()
.loadKeyMaterial(keyStore("client-keystore.jks", password), password)
.loadTrustMaterial(new File("client-truststore.jks"),"secret".toCharArray()).build();
HttpClient client = HttpClients.custom().setSSLContext(sslContext).build();
return builder
.requestFactory(new HttpComponentsClientHttpRequestFactory(client))
.build();
}
private KeyStore keyStore(String file, char[] password) throws Exception {
KeyStore keyStore = KeyStore.getInstance("jks");
File key = ResourceUtils.getFile(file);
try (InputStream in = new FileInputStream(key)) {
keyStore.load(in, password);
}
return keyStore;
}
This is my server code with the two methods post and get, the get is working but post is not working:
#RestController
public class HomeRestController {
#PostMapping("/hola")
public String home(Principal principal) {
return String.format("Hello %s!", principal.getName());
}
#GetMapping("/holaa")
public String homee(Principal principal) {
return String.format("Hello %s!", principal.getName());
}
}
I have this is my YML with the mutual authentication configuration:
server:
context-path: /${spring.application.name}
port: 8483
ssl:
key-store: server-keystore.keystore
key-store-password: pass123
key-alias: default
trust-store: server-truststore.jks
trust-store-password: secret
enabled: true
client-auth: need
Calling the getMaping it works, but calling the postMaping it returns to me 403.
The keystore and trustore are configured and are OK.
And in my security configuration I have:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().x509()
.subjectPrincipalRegex("CN=(.*?)(?:,|$)").userDetailsService(userDetailsService());
}
#Override
#Bean
public UserDetailsService userDetailsService() {
return (username -> {
return new User(username, "",
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
});
}
}
Why my post calling does not work?

Spring resttemplate 2 way ssl using spring boot

I'm consuming a RESTful Web Service using Spring Boot and restTemplate. The service is secured with 2 way ssl. So fare I have made this code to configure the connection. The code works but what I'm looking for is the best way to implement 2 way SSL with springs restTemplate and httpClient or another alternative using Spring Boot
#Configuration()
public class RestClientConfig {
private static final Logger log = LoggerFactory.getLogger(RestClientConfig.class);
#Bean()
#Qualifier("SSLRestOperations")
public RestOperations restOperations(ClientHttpRequestFactory clientHttpRequestFactory) throws Exception {
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
return restTemplate;
}
#Bean
public ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient) {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
// timeout
requestFactory.setReadTimeout(60 * 1000);
requestFactory.setConnectTimeout(60 * 1000);
return requestFactory;
}
#Bean
public HttpClient httpClient(#Value("${keystore.file}") Resource file, #Value("${keystore.pass}") Password password) throws Exception {
String keystorePassword = password.getDescrambled();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
TrustManagerFactory tmf =TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream instream = file.getInputStream();
InputStream instreamKey = file.getInputStream();
try {
keyStore.load(instreamKey, keystorePassword.toCharArray());
trustStore.load(instream, keystorePassword.toCharArray());
kmf.init(keyStore, keystorePassword.toCharArray());
tmf.init(trustStore);
} finally {
instream.close();
instreamKey.close();
}
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
.loadKeyMaterial(trustStore, keystorePassword.toCharArray()).build();
SSLSocketFactory socketFactory = sslcontext.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1.2" }, null, new NoopHostnameVerifier());
return HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier()) // HostnameVerifier NoopHostnameVerifier
.setSSLSocketFactory(sslsf)
.build();
}

How to use RestTemplate with Basic Auth

How do you configure RestTemplate from Spring 4.0.3.RELEASE with Apache httpclient 4.3.2? I've followed the code from SO here, and here, and even from Apache here, and it seems pretty straightforward, yet it has never worked for me. I can verify that the Authorization header is correctly sent when I use curl and postman, but the Authorization header is never sent with the following code:
public RestTemplate createBasicAuthTemplate(String username, String password) {
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
HttpClient httpClient = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credentialsProvider)
.build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate template = new RestTemplate(requestFactory);
return template;
}
and the code is called like so:
RestTemplate basicAuth = createBasicAuthTemplate("user#app.com", "password");
ResponseEntity<String> response = basicAuth.getForEntity(url, String.class);
So the questions are: How do you configure RestTemplate from Spring 4.0.3.RELEASE with Apache httpclient 4.3.2? Are there other pieces that the above code is missing? In the above code is the RestTemplate using the correct method?
The astute reader may have noticed that the Authorization header is never sent, and realized the problem. You just have to know that it is a standard protocol to send an unauthorized request, receive a 401 with a WWW-Authenticate header, and make the request again with the Authorization header (I did not know that, so this was a great learning experience).
The rest template does not send the Authentication header on the initial request (by default it is reactive rather than proactive), so if the service does not respond with a WWW-Authenticate header (as it should according to the HTTP spec) and the RestTemplate does not attempt to send the credentials after the initial response, then the call will simply fail on the intial 401 response.
Fortunately we can tell the rest template to send the credentials on the initial request rather than waiting for a 401 with a WWW-Authenticate header.
Here is the code to do this. The trick here is to override the request factory’s createHttpContext() method to take control over the HTTP context, and use this factory in constructing the RestTemplate. This code works, and uses the self-signed certificate. You may of course restructure it to your taste…
public class BasicRequestFactory extends HttpComponentsClientHttpRequestFactory {
public BasicRequestFactory(HttpClient httpClient) {
super(httpClient);
}
#Override
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
HttpHost targetHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
AuthCache authCache = new BasicAuthCache();
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
return localContext;
}
private static HttpClient createSecureClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).useTLS().build();
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
return HttpClientBuilder.create().setSSLSocketFactory(connectionFactory).build();
}
private static HttpClient createSecureClient(String username, String password) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).useTLS().build();
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
return HttpClientBuilder.create().setSSLSocketFactory(connectionFactory).setDefaultCredentialsProvider(credentialsProvider).build();
}
public static RestTemplate createTemplate(String username, String password) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
RestTemplate template = new RestTemplate(new BasicRequestFactory(createSecureClient(username, password)));
template.setErrorHandler(new NopResponseErrorHandler());
return template;
}
public static RestTemplate createTemplate() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
RestTemplate template = new RestTemplate(new BasicRequestFactory(createSecureClient()));
template.setErrorHandler(new NopResponseErrorHandler());
return template;
}
private static class NopResponseErrorHandler implements ResponseErrorHandler {
#Override
public boolean hasError(ClientHttpResponse chr) throws IOException {
return false;
}
#Override
public void handleError(ClientHttpResponse chr) throws IOException {
}
}
}

Resources