Add Kotlin samples and polish SSL bundle documentation

Closes gh-35105
pull/35165/head
Scott Frederick 2 years ago
parent ce7bf0d0af
commit d913472919

@ -84,14 +84,22 @@ See {spring-boot-autoconfigure-module-code}/ssl/PemSslBundleProperties.java[PemS
[[features.ssl.applying]] [[features.ssl.applying]]
=== Applying SSL Bundles === Applying SSL Bundles
Once configured using properties, SSL bundles can be referred to by name in configuration properties for various types of connections that are auto-configured by Spring Boot. Once configured using properties, SSL bundles can be referred to by name in configuration properties for various types of connections that are auto-configured by Spring Boot.
See the sections on <<howto#howto.webserver.configure-ssl,embedded web servers>> and <<data#data,data technologies>> for further information. See the sections on <<howto#howto.webserver.configure-ssl,embedded web servers>>, <<data#data,data technologies>>, and <<io#io.rest-client,REST clients>> for further information.
[[features.ssl.bundles]] [[features.ssl.bundles]]
=== Using SSL Bundles === Using SSL Bundles
Spring Boot auto-configures a bean of type `SslBundles` that provides access to each of the named bundles configured using the `spring.ssl.bundle` properties. Spring Boot auto-configures a bean of type `SslBundles` that provides access to each of the named bundles configured using the `spring.ssl.bundle` properties.
An `SslBundle` can be retrieved from the auto-configured `SslBundles` bean and used to create a `javax.net.ssl.SSLContext` or objects of other types from the `java.net.ssl` package that are typically used to configure SSL connectivity in other APIs.
An `SslBundle` can be retrieved from the auto-configured `SslBundles` bean and used to create objects that are used to configure SSL connectivity in client libraries.
The `SslBundle` provides a layered approach of obtaining these SSL objects:
- `getStores()` provides access to the key store and trust store `java.security.KeyStore` instances as well as any required key store password.
- `getManagers()` provides access to the `java.net.ssl.KeyManagerFactory` and `java.net.ssl.TrustManagerFactory` instances as well as the `java.net.ssl.KeyManager` and `java.net.ssl.TrustManager` arrays that they create.
- `createSslContext()` provides a convenient way to obtain a new `java.net.ssl.SSLContext` instance.
In addition, the `SslBundle` provides details about the key being used, the protocol to use and any option that should be applied to the SSL engine.
The following example shows retrieving an `SslBundle` and using it to create an `SSLContext`: The following example shows retrieving an `SslBundle` and using it to create an `SSLContext`:

@ -15,7 +15,6 @@ include::code:MyService[]
`RestTemplateBuilder` includes a number of useful methods that can be used to quickly configure a `RestTemplate`. `RestTemplateBuilder` includes a number of useful methods that can be used to quickly configure a `RestTemplate`.
For example, to add BASIC authentication support, you can use `builder.basicAuthentication("user", "password").build()`. For example, to add BASIC authentication support, you can use `builder.basicAuthentication("user", "password").build()`.
To add SSL support using an <<features#features.ssl.bundles,SSL bundle>>, you can use `builder.setSslBundle(sslBundle).build()`.
@ -45,6 +44,14 @@ In addition to replacing the auto-configured builder, this also prevents any `Re
[[io.rest-client.resttemplate.ssl]]
==== RestTemplate SSL Support
If you need custom SSL configuration on the `RestTemplate`, you can apply an <<features#features.ssl.bundles,SSL bundle>> to the `RestTemplateBuilder` as shown in this example:
include::code:MyService[]
[[io.rest-client.webclient]] [[io.rest-client.webclient]]
=== WebClient === WebClient
If you have Spring WebFlux on your classpath, you can also choose to use `WebClient` to call remote REST services. If you have Spring WebFlux on your classpath, you can also choose to use `WebClient` to call remote REST services.

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2021 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,6 @@
package org.springframework.boot.docs.io.restclient.resttemplate; package org.springframework.boot.docs.io.restclient.resttemplate;
class Details { public class Details {
} }

@ -0,0 +1,38 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docs.io.restclient.resttemplate.ssl;
import org.springframework.boot.docs.io.restclient.resttemplate.Details;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class MyService {
private final RestTemplate restTemplate;
public MyService(RestTemplateBuilder restTemplateBuilder, SslBundles sslBundles) {
this.restTemplate = restTemplateBuilder.setSslBundle(sslBundles.getBundle("mybundle")).build();
}
public Details someRestCall(String name) {
return this.restTemplate.getForObject("/{name}/details", Details.class, name);
}
}

@ -0,0 +1,21 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docs.io.restclient.webclient;
public class Details {
}

@ -16,7 +16,6 @@
package org.springframework.boot.docs.io.restclient.webclient; package org.springframework.boot.docs.io.restclient.webclient;
import org.neo4j.cypherdsl.core.Relationship.Details;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

@ -16,10 +16,10 @@
package org.springframework.boot.docs.io.restclient.webclient.ssl; package org.springframework.boot.docs.io.restclient.webclient.ssl;
import org.neo4j.cypherdsl.core.Relationship.Details;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientSsl; import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientSsl;
import org.springframework.boot.docs.io.restclient.webclient.Details;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;

@ -0,0 +1,31 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docs.features.ssl.bundles
import org.springframework.boot.ssl.SslBundles
import org.springframework.stereotype.Component
@Component
@Suppress("UNUSED_VARIABLE")
class MyComponent(sslBundles: SslBundles) {
init {
val sslBundle = sslBundles.getBundle("mybundle")
val sslContext = sslBundle.createSslContext()
// do something with the created sslContext
}
}

@ -20,7 +20,6 @@ import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.web.client.RestTemplate import org.springframework.web.client.RestTemplate
@Suppress("UNUSED_PARAMETER")
@Service @Service
class MyService(restTemplateBuilder: RestTemplateBuilder) { class MyService(restTemplateBuilder: RestTemplateBuilder) {
@ -31,10 +30,7 @@ class MyService(restTemplateBuilder: RestTemplateBuilder) {
} }
fun someRestCall(name: String): Details { fun someRestCall(name: String): Details {
return restTemplate.getForObject( return restTemplate.getForObject("/{name}/details", Details::class.java, name)!!
"/{name}/details",
Details::class.java, name
)!!
} }
} }

@ -0,0 +1,37 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docs.io.restclient.resttemplate.ssl
import org.springframework.boot.docs.io.restclient.resttemplate.Details
import org.springframework.boot.ssl.SslBundles
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.stereotype.Service
import org.springframework.web.client.RestTemplate
@Service
class MyService(restTemplateBuilder: RestTemplateBuilder, sslBundles: SslBundles) {
private val restTemplate: RestTemplate
init {
restTemplate = restTemplateBuilder.setSslBundle(sslBundles.getBundle("mybundle")).build()
}
fun someRestCall(name: String): Details {
return restTemplate.getForObject("/{name}/details", Details::class.java, name)!!
}
}

@ -0,0 +1,19 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docs.io.restclient.webclient
class Details

@ -16,7 +16,6 @@
package org.springframework.boot.docs.io.restclient.webclient package org.springframework.boot.docs.io.restclient.webclient
import org.neo4j.cypherdsl.core.Relationship
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.web.reactive.function.client.WebClient import org.springframework.web.reactive.function.client.WebClient
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
@ -30,10 +29,8 @@ class MyService(webClientBuilder: WebClient.Builder) {
webClient = webClientBuilder.baseUrl("https://example.org").build() webClient = webClientBuilder.baseUrl("https://example.org").build()
} }
fun someRestCall(name: String?): Mono<Relationship.Details> { fun someRestCall(name: String?): Mono<Details> {
return webClient.get().uri("/{name}/details", name).retrieve().bodyToMono( return webClient.get().uri("/{name}/details", name).retrieve().bodyToMono(Details::class.java)
Relationship.Details::class.java
)
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2022 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,8 +16,8 @@
package org.springframework.boot.docs.io.restclient.webclient.ssl package org.springframework.boot.docs.io.restclient.webclient.ssl
import org.neo4j.cypherdsl.core.Relationship
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientSsl import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientSsl
import org.springframework.boot.docs.io.restclient.webclient.Details
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.web.reactive.function.client.WebClient import org.springframework.web.reactive.function.client.WebClient
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
@ -31,10 +31,8 @@ class MyService(webClientBuilder: WebClient.Builder, ssl: WebClientSsl) {
webClient = webClientBuilder.baseUrl("https://example.org").apply(ssl.fromBundle("mybundle")).build() webClient = webClientBuilder.baseUrl("https://example.org").apply(ssl.fromBundle("mybundle")).build()
} }
fun someRestCall(name: String?): Mono<Relationship.Details> { fun someRestCall(name: String?): Mono<Details> {
return webClient.get().uri("/{name}/details", name).retrieve().bodyToMono( return webClient.get().uri("/{name}/details", name).retrieve().bodyToMono(Details::class.java)
Relationship.Details::class.java
)
} }
} }

Loading…
Cancel
Save