How do we configure the Ssl Bundle to use InsecureTrustManagerFactory or custom TrustManagerFactory or skip hostname verification? Couldn't find these details in the documentation. Thanks
Comment From: Nikunj2788
If you need to work with self-signed certificates or for testing purposes, consider using an InsecureTrustManagerFactory. This involves creating a custom SSLContext with an InsecureTrustManager and setting it as the default for your HTTPS connections.
For the Custom manager Factory you have the scenarios where you have specific truststore requirements, create a custom SSLContext with a TrustManagerFactory initialized with your custom truststore. Ensure that you load your truststore appropriately and initialize the SSLContext with the custom trust manager.
Comment From: syedyusufh
@Nikunj2788 ask is how to do the same via Ssl Bundles. Thanks
Comment From: wilkinsona
@syedyusufh if you're interacting with a server that uses a self-signed certificate, have you considered trusting that certificate alone on the client-side? That, I think, would be the SSL bundle way of doing things. If you want the client to trust all self-signed certificates or to skip hostname verification, that should be done with client-specific configuration and not through SSL bundles.
Comment From: syedyusufh
@wilkinsona thanks for your comments.
My understanding is that Ssl Bundle manages the trustStore, trustStrategy, etc as part of the Ssl Bundle configuration via application.properties. How do we alter the trust strategy of the Ssl Bundle managed TrustStore still benefiting from the Ssl Bundle benefits?
In other words, how can I construct a full beneficial Ssl Bundle of my underlying JKS with trustStore, trustStrategy programmatically?
Thanks
Comment From: wilkinsona
I don't think I understand why you need both. You can configure an SSL bundle that trusts the server's unsigned certificates or you can configure whatever HTTP client you're using to use an insecure trust manager. Doing one of these negates the need for the other, does it not?
Comment From: syedyusufh
Let us please consider the below sample from Spring.io Blog on how to setup SSL for WebClient via Ssl Bundle,
@Service
public class MyService {
private final WebClient webClient;
public MyService(WebClient.Builder webClientBuilder, WebClientSsl ssl) {
this.webClient = webClientBuilder.baseUrl("https://example.org").apply(ssl.fromBundle("mybundle")).build();
}
}
How do we now configure the underlying (WebClientSsl) TrustStore to ignore hostNameVerification? We were able to do the same without Ssl Bundle by configuring SslContext, TrustManagerFactory, KeyManagerFactory like below.
``` // Create an SSL context that uses that certificate return SslContextBuilder.forClient() .keyManager(keyManagerFactory) .build();
**Comment From: scottfrederick**
I agree with Andy's statement [above](https://github.com/spring-projects/spring-boot/issues/38920#issuecomment-1874130343):
> If you want the client to trust all self-signed certificates or to skip hostname verification, that should be done with client-specific configuration and not through SSL bundles.
Disabling hostname verification is a very dangerous thing to do. It might be useful for testing sometimes, but I don't think Spring Boot should do anything more to make this easy to do so that user's don't mistakenly disable verification in production applications.
> We were able to do the same without Ssl Bundle by configuring SslContext, TrustManagerFactory, KeyManagerFactory like below.
One option would be to keep your code that sets up the `SSLContext` manually, but retrieve the trust material from a configured SSL bundle. To do this, you'd need to auto-wire an instance of `SslBundles` into your code, retrieve the bundle you want using `SslBundles.getBundle(String name)`. Once you get an `SslBundle` from `SslBundles`, you can use `SslBundle.getManagers()` to get any `KeyManagerFactory` and `TrustManagerFactory` instances you need to configure the `SSLContext`.
**Comment From: syedyusufh**
Hi @scottfrederick thanks for your inputs.
Like any enterprise we have both modern and legacy systems, so the custom `TrustStrategy` is a much needed one. The default SSL behavior out-of-box does NOT fit every system :(
`Ssl Bundles` solve the problem of application restart to update the application's `Ssl Context` due to the underlying certificate change and this is an awesome feature in a Microservices environment where multiple applications are run.
> but I don't think Spring Boot should do anything more to make this easy to do so that user's don't mistakenly disable verification in production applications.
Spring Boot framework today provides options to configure your own `TrustStrategy` when setting up the **SSL** either via `Apache Http` or `Netty` implementations. For instance, we have out of framework implementations like `InSecureTrustManagerFactory` though with a warning and a disclaimer.
> Once you get an SslBundle from SslBundles, you can use SslBundle.getManagers() to get any KeyManagerFactory and TrustManagerFactory instances you need to configure the SSLContext
Can we get the Ssl Bundle benefit of dynamic reloading of Ssl Context if the framework managed `KeyManagerFactory` and `TrustManagerFactory` are overridden?
Thanks
**Comment From: scottfrederick**
@syedyusufh I'm afraid it's still not completely clear what you're trying to accomplish. It seems that you are mostly concerned with configuring SSL for client connections. Reloading of SSL material with SSL bundles is [only supported for server-side connections when using Tomcat or Netty as an embedded web server,](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.ssl.reloading) so your questions about reloading the SSL context would not apply to your client connections.
I think we would make more progress on this discussion if we had a small code sample of what you are doing now. Can you provide a complete minimal application that demonstrates your use case, and share it with us by pushing it to a separate repository on GitHub or by zipping it and attaching it to this issue? That would make it much easier for us to see if there's anything we can add to our APIs for custom configuration of client connections.
**Comment From: syedyusufh**
> Reloading of SSL material with SSL bundles is [only supported for server-side connections when using Tomcat or Netty as an embedded web server,](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.ssl.reloading) so your questions about reloading the SSL context would not apply to your client connections
I got it now. Sorry, I was with the impression `Ssl Bundle` applicable components are all reloadable by default.
Kindly consider allowing an option to customize the `TrustStrategy` for client connections when we use `Ssl Bundles`
Thanks
**Comment From: guybedo**
@syedyusufh i'm a bit late to the party, but i had a similar situation i think where i needed to connect to a https server.
I needed to provide client cert to connect to the server and needed to accept the server's self signed cert.
It wasn't possible to customize the SSLBundle trustmanagers / trustmanagerfactory so i ended up using the SSLBundle only to load the keys from the files. I didn't use it to build my RestTemplate and initialized the SSLContext with the SSLBundle's KeyManager[].
So, instead of:
SslBundle sslBundle = sslBundles.getBundle("rest");
return builder .setSslBundle(sslBundle) .messageConverters(converters) .build();
i did:
SslBundle sslBundle = sslBundles.getBundle("rest"); KeyManager[] keyManagers = sslBundle.getManagers().getKeyManagers(); SslUtils.configureDefaultSslSockerFactory(keyManagers); return builder .messageConverters(converters) .build();
with SSLUtils:
public class SslUtils {
public static TrustManager[] trustAllCerts() {
return new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs,
String authType) {
}
}
};
}
public static void configureDefaultSslSockerFactory(KeyManager[] keyManagers) {
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(keyManagers, trustAllCerts(), new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
} ```
Comment From: scottfrederick
I am still of the opinion that Spring Boot should not have a built-in ability to disable hostname verification or otherwise configure insecure connections. Users can do this now by creating their own client connections as has been mentioned above and demonstrated by @guybedo. We could make it simpler to customize a connection that has been created by Spring Boot, which is also suggested more generally in #39035. I'll close this issue as a duplicate.