diff --git a/spring-boot-modules/spring-boot-ssl-bundles/README.md b/spring-boot-modules/spring-boot-ssl-bundles/README.md new file mode 100644 index 0000000000..5616cce48b --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/README.md @@ -0,0 +1 @@ +## Relevant Articles diff --git a/spring-boot-modules/spring-boot-ssl-bundles/pom.xml b/spring-boot-modules/spring-boot-ssl-bundles/pom.xml new file mode 100644 index 0000000000..056d0308c2 --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + springbootsslbundles + spring-boot-ssl-bundles + jar + Module for showing usage of SSL Bundles + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + org.apache.httpcomponents.client5 + httpclient5-fluent + ${apache.client5.version} + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + 5.0.3 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SSLBundlesApp.java b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SSLBundlesApp.java new file mode 100644 index 0000000000..f6cfb35d1e --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SSLBundlesApp.java @@ -0,0 +1,19 @@ +package com.baeldung.springbootsslbundles; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; +import org.springframework.boot.ssl.SslBundles; + +@SpringBootApplication +public class SSLBundlesApp { + public static void main(String[] args) { + SpringApplication.run(SSLBundlesApp.class, args); + } + @Bean + public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder, SslBundles sslBundles) { + return restTemplateBuilder.setSslBundle(sslBundles.getBundle("secure-service")).build(); + } +} diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureRestTemplateConfig.java b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureRestTemplateConfig.java new file mode 100644 index 0000000000..48eda219dd --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureRestTemplateConfig.java @@ -0,0 +1,38 @@ +package com.baeldung.springbootsslbundles; + +import org.apache.hc.client5.http.classic.HttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.io.HttpClientConnectionManager; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ssl.NoSuchSslBundleException; +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.context.annotation.Bean; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import javax.net.ssl.SSLContext; + +@Component +public class SecureRestTemplateConfig { + private final SSLContext sslContext; + + @Autowired + public SecureRestTemplateConfig(SslBundles sslBundles) throws NoSuchSslBundleException { + SslBundle sslBundle = sslBundles.getBundle("secure-service"); + this.sslContext = sslBundle.createSslContext(); + } + + @Bean + public RestTemplate secureRestTemplate() { + final SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create().setSslContext(this.sslContext).build(); + final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(sslSocketFactory).build(); + HttpClient httpClient = HttpClients.custom().setConnectionManager(cm).evictExpiredConnections().build(); + HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); + return new RestTemplate(factory); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureServiceRestApi.java b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureServiceRestApi.java new file mode 100644 index 0000000000..3ed919b957 --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureServiceRestApi.java @@ -0,0 +1,28 @@ +package com.baeldung.springbootsslbundles; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class SecureServiceRestApi { + private final RestTemplate restTemplate; + + @Autowired + public SecureServiceRestApi(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + public String fetchData(String dataId) { + ResponseEntity response = restTemplate.exchange( + "https://secure-service.com/api/data/{id}", + HttpMethod.GET, + null, + String.class, + dataId + ); + return response.getBody(); + } +} diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/application.yml b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/application.yml new file mode 100644 index 0000000000..1598645805 --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/application.yml @@ -0,0 +1,11 @@ +spring: + ssl: + bundle: + jks: + secure-service: + key: + alias: "secure-service" + keystore: + location: "classpath:keystore.p12" + password: "FooBar" + type: "PKCS12" \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/cert.pem b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/cert.pem new file mode 100644 index 0000000000..82ed122a80 --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIUCJcVMwyhLy/ln+ENMXbSWcsO0aswDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzA5MDUxNjAyMzdaFw0yNDA5 +MDQxNjAyMzdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDMNn+ZmPfR4FUyG6PVGBB2rOAnIHqFqYMVyDUOtZja +9CxpgbQjHRwwWaUWcYzLPOsvN/tMC8BazAFHSI2KIeNKgjAesv9JTumqgFXdOmw8 +KT7a9C1IQXnCMhlbp9J7c7CLvjAvZvZBghxFLc7xBZo9rWA67QMZoOhXvdMoKv4G +5v9qD1ZqIKlCxJQrdErVUKyZPztlIWNqzPy9BJzFlBea2ArfrASulqJuWGyO09+o +6ABNgUAicp/zfCOeKIe9cni0oZj6Buwk4eVdYESzVohBO52h95KtN17Y/Tw+U8W5 +Szq9tit6Vkupbe8tih7Bkdnj22WeCLVwWdXCp1kJw2kFDJTiC3wQRa6P0OrVpPGx +Z5SmG9eSCz22alA+I521ZG85hmPDt3BleYRYlCtcW7GFT/7zLBEwlN93lY5Os1jj +PRS8o5eIg8UhTbU4QEaZRYcLzaFy0asfKfa4ZF3mH5whh/w07SEEBAKDfQPpiz3T +migd+r9qUnPWeoE8Hi7lA1KzUd4YeM2yNHqXoQiARjHkM4yrX6vVlfT+itVbrpqF +a5J7PjL26w+DsxvRt9Ad5gpOdDzuy5m2V6lphMDjeZoG4OXgBzQQ1YxK1r6wkI4U +ZwRNrb+BxmQebQHnXKEXI7jgS45uoFENwolIHm9Dou5VYGLI0z+/pDReugCcw2lO +/QIDAQABo1MwUTAdBgNVHQ4EFgQUlSkON/OM9HCXeaQ7VWQuiEwY2iAwHwYDVR0j +BBgwFoAUlSkON/OM9HCXeaQ7VWQuiEwY2iAwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEAD+8sPSQR3+A4F9z704OOy1Mo6bvbnIuK9UdN7d4/zh+e +AoloyTFPLPZIldg9hXwCvrKjrfqS5YUKmXIp9tetX7ns13CeDFcqVwZfPnqjzdNN +ad255LEwMjIUm9hSNEV6AQBKW8E+a590SrUamEdkFm4fcUB1LaINwyJjls7C0VB2 +JL50OloaUlv0IMnAPRVp0Adlt9xs69R2B8Q4i297FvHB1PI7VMLYqNnX2+tnvszO +HvWtIqm6foyReDLfC0n87cuEBV7/9304V5vgEj20TR19isd0LffJDD1ujDXvN8dS +uGOB1VLRxAPonr9Iqk358EJ1T22uEcMdKE+sMnCBjw2fYIYRfjhGN+m6U6sb4MrF +zFUI6qB7W7T/5iukiRb4pLQ0OGgKOwYxpZoxcB3Ldjo5x58uKNOTNJ5zEJ8HUofA +BNfty10D3m3DlSyYbf7m1UUM0jj2l83LBGQzhGGUZgCnCsMczLrj64Gvf2iLGmCF +gu5zrxL01dptBkvTsYJwYBA67BBS4FcgYNMGx3m1uPsVUUIguJxufXWYfbub74QV +a1SH1NjO8HR3DLDU+S92tyTKWOUzJ5qOegEsR2cutVRzDuVTsFy7kayuNv/uLRrG +3P2HnUo8PG/nmysReBk6CGycUiDTt55DoPYGoQ5l19xTlkIt7ulNg7yX5pwFMeE= +-----END CERTIFICATE----- diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/key.pem b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/key.pem new file mode 100644 index 0000000000..b4202e9a8e --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/key.pem @@ -0,0 +1,54 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +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 +7NNrMLXj3PGrZ2vzKDGSAU1LzLOUrJ4m +-----END ENCRYPTED PRIVATE KEY----- diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/keystore.p12 b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/keystore.p12 new file mode 100644 index 0000000000..f58b355467 Binary files /dev/null and b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/keystore.p12 differ diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/static/index.html b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/static/index.html new file mode 100644 index 0000000000..117910cc89 --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/main/resources/static/index.html @@ -0,0 +1,13 @@ + + + + + Spring SSL Bundler Demo Application + + +

Spring SSL Bundler Demo Application

+

+ This is a sample application that can be built as native executable. +

+ + diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/test/java/com/baeldung/springbootsslbundles/SSLBundleApplicationTests.java b/spring-boot-modules/spring-boot-ssl-bundles/src/test/java/com/baeldung/springbootsslbundles/SSLBundleApplicationTests.java new file mode 100644 index 0000000000..876641c8b5 --- /dev/null +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/test/java/com/baeldung/springbootsslbundles/SSLBundleApplicationTests.java @@ -0,0 +1,12 @@ +package com.baeldung.springbootsslbundles; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SSLBundleApplicationTests { + @Test + void contextLoads() { + + } +}