Last active
October 20, 2022 10:16
-
-
Save fzakaria/c94db498a479ee1711f571cad2776b34 to your computer and use it in GitHub Desktop.
How to properly use an http client with a self signed certificate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Too many examples on the internet demonstrate using self-signed certificates by disabling hostname verification | |
or providing a weak TrustManager (i.e. SelfSignedTrustManager). | |
This example shows how to properly start a server & client in the same JVM where the client knows about the | |
generated self-signed certificate. | |
Also it's all done programmatically! Avoid using keytool and pulling in heavy dependencies like BouncyCastle!~ | |
**/ | |
public class SecureServerTest { | |
/** | |
* Use netty to create a self signed certificate easily. | |
If you don't use netty you can easily make one similarily using the JDK | |
private static final SelfSignedCertificate SELF_SIGNED_CERTIFICATE = uncheckedSelfSignedCertificate("localhost"); | |
/** | |
* Load the self-signed certificate into a KeyStore | |
*/ | |
private static final KeyStore KEY_STORE_WITH_SELF_SIGNED = loadSelfSignedCertificate(SELF_SIGNED_CERTIFICATE); | |
private static final HttpServerOptions TEST_OPTIONS = | |
HttpServerOptions.builder().withPrivateKeyAndCertificate(SELF_SIGNED_CERTIFICATE.key(), SELF_SIGNED_CERTIFICATE.cert()) | |
.build(); | |
@Test | |
public void testServerWithSSL() throws Exception { | |
/** | |
* This example uses Apache HttpClient however it would be similar for other clients. | |
Load the trust store we created that knows about our self-signed certificate. | |
*/ | |
final SSLContext sslContext = SSLContexts.custom() | |
.loadTrustMaterial(KEY_STORE_WITH_SELF_SIGNED, null) | |
.build(); | |
/* Create the server with SSL mode enabled with whatever framework you are using. */ | |
try (HttpServer server = HttpServer.listen(0, TEST_OPTIONS)) { | |
/* Set the SSLContext for Apache's httpClient */ | |
try (CloseableHttpClient client = HttpClientBuilder.create().setSSLContext(sslContext).build()) { | |
/* Unirest is just a simple fluent wrapper over Apache's http client. */ | |
Unirest.setHttpClient(client); | |
String url = String.format("https://localhost:%s", server.getPort()); | |
com.mashape.unirest.http.HttpResponse<String> response = Unirest.get(url).asString(); | |
Assertions.assertThat(response.getStatus()).isEqualTo(200); | |
} | |
} | |
} | |
private static SelfSignedCertificate uncheckedSelfSignedCertificate(String fqdn) { | |
try { | |
return new SelfSignedCertificate(fqdn); | |
} catch (CertificateException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
private static KeyStore loadSelfSignedCertificate(SelfSignedCertificate certificate) { | |
try { | |
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); | |
keyStore.load(null, null); | |
keyStore.setCertificateEntry("localhost", certificate.cert()); | |
return keyStore; | |
} catch (KeyStoreException | CertificateException | IOException | NoSuchAlgorithmException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment