Skip to content

Commit ee89e0e

Browse files
committed
Fix client auth with Jetty
Fixes gh-17541
1 parent e07889b commit ee89e0e

File tree

6 files changed

+15
-50
lines changed

6 files changed

+15
-50
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ class SslServerCustomizer implements JettyServerCustomizer {
6868

6969
@Override
7070
public void customize(Server server) {
71-
SslContextFactory sslContextFactory = new SslContextFactory();
71+
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
72+
sslContextFactory.setEndpointIdentificationAlgorithm(null);
7273
configureSsl(sslContextFactory, this.ssl, this.sslStoreProvider);
7374
ServerConnector connector = createConnector(server, sslContextFactory, this.address);
7475
server.setConnectors(new Connector[] { connector });
@@ -131,7 +132,7 @@ private ServerConnector createHttp2ServerConnector(Server server, HttpConfigurat
131132
* @param ssl the ssl details.
132133
* @param sslStoreProvider the ssl store provider
133134
*/
134-
protected void configureSsl(SslContextFactory factory, Ssl ssl, SslStoreProvider sslStoreProvider) {
135+
protected void configureSsl(SslContextFactory.Server factory, Ssl ssl, SslStoreProvider sslStoreProvider) {
135136
factory.setProtocol(ssl.getProtocol());
136137
configureSslClientAuth(factory, ssl);
137138
configureSslPasswords(factory, ssl);
@@ -158,7 +159,7 @@ protected void configureSsl(SslContextFactory factory, Ssl ssl, SslStoreProvider
158159
}
159160
}
160161

161-
private void configureSslClientAuth(SslContextFactory factory, Ssl ssl) {
162+
private void configureSslClientAuth(SslContextFactory.Server factory, Ssl ssl) {
162163
if (ssl.getClientAuth() == Ssl.ClientAuth.NEED) {
163164
factory.setNeedClientAuth(true);
164165
factory.setWantClientAuth(true);

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizerTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ public void configureSslWhenSslIsEnabledWithNoKeyStoreThrowsWebServerException()
8181
Ssl ssl = new Ssl();
8282
SslServerCustomizer customizer = new SslServerCustomizer(null, ssl, null, null);
8383
assertThatExceptionOfType(Exception.class)
84-
.isThrownBy(() -> customizer.configureSsl(new SslContextFactory(), ssl, null)).satisfies((ex) -> {
84+
.isThrownBy(() -> customizer.configureSsl(new SslContextFactory.Server(), ssl, null))
85+
.satisfies((ex) -> {
8586
assertThat(ex).isInstanceOf(WebServerException.class);
8687
assertThat(ex).hasMessageContaining("Could not load key store 'null'");
8788
});

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,11 @@
2121
import java.net.InetSocketAddress;
2222
import java.nio.charset.StandardCharsets;
2323
import java.security.KeyStore;
24-
import java.security.PrivateKey;
25-
import java.security.cert.X509Certificate;
2624
import java.time.Duration;
2725
import java.util.Arrays;
2826

29-
import javax.net.ssl.KeyManager;
3027
import javax.net.ssl.KeyManagerFactory;
3128
import javax.net.ssl.SSLException;
32-
import javax.net.ssl.X509KeyManager;
3329

3430
import io.netty.channel.ChannelHandlerContext;
3531
import io.netty.channel.ChannelInboundHandlerAdapter;
@@ -170,22 +166,11 @@ protected ReactorClientHttpConnector buildTrustAllSslWithClientKeyConnector() th
170166
KeyManagerFactory clientKeyManagerFactory = KeyManagerFactory
171167
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
172168
clientKeyManagerFactory.init(clientKeyStore, "password".toCharArray());
173-
for (KeyManager keyManager : clientKeyManagerFactory.getKeyManagers()) {
174-
if (keyManager instanceof X509KeyManager) {
175-
X509KeyManager x509KeyManager = (X509KeyManager) keyManager;
176-
PrivateKey privateKey = x509KeyManager.getPrivateKey("spring-boot");
177-
if (privateKey != null) {
178-
X509Certificate[] certificateChain = x509KeyManager.getCertificateChain("spring-boot");
179-
SslContextBuilder builder = SslContextBuilder.forClient().sslProvider(SslProvider.JDK)
180-
.trustManager(InsecureTrustManagerFactory.INSTANCE)
181-
.keyManager(privateKey, certificateChain);
182-
HttpClient client = HttpClient.create().wiretap(true)
183-
.secure((sslContextSpec) -> sslContextSpec.sslContext(builder));
184-
return new ReactorClientHttpConnector(client);
185-
}
186-
}
187-
}
188-
throw new IllegalStateException("Key with alias 'spring-boot' not found");
169+
SslContextBuilder builder = SslContextBuilder.forClient().sslProvider(SslProvider.JDK)
170+
.trustManager(InsecureTrustManagerFactory.INSTANCE).keyManager(clientKeyManagerFactory);
171+
HttpClient client = HttpClient.create().wiretap(true)
172+
.secure((sslContextSpec) -> sslContextSpec.sslContext(builder));
173+
return new ReactorClientHttpConnector(client);
189174
}
190175

191176
protected void testClientAuthSuccess(Ssl sslConfiguration, ReactorClientHttpConnector clientConnector) {

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import java.net.InetSocketAddress;
2626
import java.net.MalformedURLException;
2727
import java.net.ServerSocket;
28-
import java.net.Socket;
2928
import java.net.URI;
3029
import java.net.URISyntaxException;
3130
import java.net.URL;
@@ -75,8 +74,6 @@
7574
import org.apache.http.impl.client.HttpClientBuilder;
7675
import org.apache.http.impl.client.HttpClients;
7776
import org.apache.http.protocol.HttpContext;
78-
import org.apache.http.ssl.PrivateKeyDetails;
79-
import org.apache.http.ssl.PrivateKeyStrategy;
8077
import org.apache.http.ssl.SSLContextBuilder;
8178
import org.apache.http.ssl.TrustStrategy;
8279
import org.apache.jasper.EmbeddedServletOptions;
@@ -402,7 +399,7 @@ public void sslKeyAlias() throws Exception {
402399
new ExampleServlet(true, false), "/hello");
403400
this.webServer = factory.getWebServer(registration);
404401
this.webServer.start();
405-
TrustStrategy trustStrategy = new SerialNumberValidatingTrustSelfSignedStrategy("5c7ae101");
402+
TrustStrategy trustStrategy = new SerialNumberValidatingTrustSelfSignedStrategy("3a3aaec8");
406403
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build();
407404
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext))
408405
.build();
@@ -464,14 +461,7 @@ public void pkcs12KeyStoreAndTrustStore() throws Exception {
464461
keyStore.load(new FileInputStream(new File("src/test/resources/test.p12")), "secret".toCharArray());
465462
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
466463
new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy())
467-
.loadKeyMaterial(keyStore, "secret".toCharArray(), new PrivateKeyStrategy() {
468-
469-
@Override
470-
public String chooseAlias(Map<String, PrivateKeyDetails> aliases, Socket socket) {
471-
return "spring-boot";
472-
}
473-
474-
}).build());
464+
.loadKeyMaterial(keyStore, "secret".toCharArray()).build());
475465
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
476466
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
477467
assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory)).isEqualTo("test");
@@ -488,13 +478,7 @@ public void sslNeedsClientAuthenticationSucceedsWithClientCertificate() throws E
488478
keyStore.load(new FileInputStream(new File("src/test/resources/test.jks")), "secret".toCharArray());
489479
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
490480
new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy())
491-
.loadKeyMaterial(keyStore, "password".toCharArray(), new PrivateKeyStrategy() {
492-
493-
@Override
494-
public String chooseAlias(Map<String, PrivateKeyDetails> aliases, Socket socket) {
495-
return "spring-boot";
496-
}
497-
}).build());
481+
.loadKeyMaterial(keyStore, "password".toCharArray()).build());
498482
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
499483
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
500484
assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory)).isEqualTo("test");
@@ -565,13 +549,7 @@ public void sslWithCustomSslStoreProvider() throws Exception {
565549
keyStore.load(new FileInputStream(new File("src/test/resources/test.jks")), "secret".toCharArray());
566550
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
567551
new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy())
568-
.loadKeyMaterial(keyStore, "password".toCharArray(), new PrivateKeyStrategy() {
569-
570-
@Override
571-
public String chooseAlias(Map<String, PrivateKeyDetails> aliases, Socket socket) {
572-
return "spring-boot";
573-
}
574-
}).build());
552+
.loadKeyMaterial(keyStore, "password".toCharArray()).build());
575553
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
576554
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
577555
assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory)).isEqualTo("test");
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)