Skip to content

Commit d33962f

Browse files
committed
Merge pull request #50301 from kwondh5217
* fix/50246-sni-fallback: Polish "Fall back to default SSL provider for unmapped SNI hostnames" Fall back to default SSL provider for unmapped SNI hostnames Closes gh-50301
2 parents b58a5b1 + 8221bdb commit d33962f

2 files changed

Lines changed: 82 additions & 5 deletions

File tree

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,13 @@ public HttpServer apply(HttpServer server) {
7575
}
7676

7777
private void applySecurity(SslContextSpec spec) {
78-
spec.sslContext(this.sslProvider.getSslContext()).setSniAsyncMappings((serverName, promise) -> {
79-
SslProvider provider = (serverName != null) ? this.serverNameSslProviders.get(serverName)
80-
: this.sslProvider;
81-
return promise.setSuccess(provider);
82-
});
78+
spec.sslContext(this.sslProvider.getSslContext())
79+
.setSniAsyncMappings((serverName, promise) -> promise.setSuccess(getSslProvider(serverName)));
80+
}
81+
82+
SslProvider getSslProvider(String serverName) {
83+
return (serverName != null) ? this.serverNameSslProviders.getOrDefault(serverName, this.sslProvider)
84+
: this.sslProvider;
8385
}
8486

8587
void updateSslBundle(String serverName, SslBundle sslBundle) {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.web.embedded.netty;
18+
19+
import java.util.Collections;
20+
import java.util.Map;
21+
22+
import org.junit.jupiter.api.Test;
23+
import reactor.netty.tcp.SslProvider;
24+
25+
import org.springframework.boot.ssl.SslBundle;
26+
import org.springframework.boot.ssl.pem.PemSslStoreBundle;
27+
import org.springframework.boot.ssl.pem.PemSslStoreDetails;
28+
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
29+
import org.springframework.boot.web.server.Ssl;
30+
31+
import static org.assertj.core.api.Assertions.assertThat;
32+
33+
/**
34+
* Tests for {@link SslServerCustomizer}.
35+
*
36+
* @author Daeho Kwon
37+
*/
38+
class SslServerCustomizerTests {
39+
40+
@Test
41+
@WithPackageResources({ "1.key", "1.crt", "2.key", "2.crt" })
42+
void getSslProviderReturnsMappedProviderForKnownServerName() {
43+
SslBundle defaultBundle = createBundle("1.key", "1.crt");
44+
SslBundle mappedBundle = createBundle("2.key", "2.crt");
45+
SslServerCustomizer customizer = new SslServerCustomizer(null, Ssl.ClientAuth.NONE, defaultBundle,
46+
Map.of("mapped.example", mappedBundle));
47+
SslProvider mapped = customizer.getSslProvider("mapped.example");
48+
assertThat(mapped).isNotNull().isNotSameAs(customizer.getSslProvider(null));
49+
}
50+
51+
@Test
52+
@WithPackageResources({ "1.key", "1.crt", "2.key", "2.crt" })
53+
void getSslProviderFallsBackToDefaultWhenServerNameIsUnmapped() {
54+
SslBundle defaultBundle = createBundle("1.key", "1.crt");
55+
SslBundle mappedBundle = createBundle("2.key", "2.crt");
56+
SslServerCustomizer customizer = new SslServerCustomizer(null, Ssl.ClientAuth.NONE, defaultBundle,
57+
Map.of("mapped.example", mappedBundle));
58+
assertThat(customizer.getSslProvider("unmapped.example")).isSameAs(customizer.getSslProvider(null));
59+
}
60+
61+
@Test
62+
@WithPackageResources({ "1.key", "1.crt" })
63+
void getSslProviderReturnsDefaultWhenServerNameIsNull() {
64+
SslBundle defaultBundle = createBundle("1.key", "1.crt");
65+
SslServerCustomizer customizer = new SslServerCustomizer(null, Ssl.ClientAuth.NONE, defaultBundle,
66+
Collections.emptyMap());
67+
assertThat(customizer.getSslProvider(null)).isNotNull();
68+
}
69+
70+
private static SslBundle createBundle(String key, String certificate) {
71+
return SslBundle.of(new PemSslStoreBundle(
72+
new PemSslStoreDetails(null, "classpath:" + certificate, "classpath:" + key), null));
73+
}
74+
75+
}

0 commit comments

Comments
 (0)