From f28e3d54c5de45e33e08fde21a42cd61c442cbeb Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 17 Jun 2016 20:42:33 +0100 Subject: [PATCH] Upgrade to Tomcat 8.5.3 This commit changes the default version of Tomcat to 8.5.3 while also retaining support for Tomcat 8.0 and 7.0. The main difference in 8.5 is that the ServerSocketFactory abstraction that allowed the TrustStore and KeyStore to be configured programatically no longer exists. This logic has been replaced with the use of a custom URL protocol (springbootssl) that provides access to the key store and trust store of an SslStoreProvider. In addition to working with 8.5, this approach has the advantage of also working with 8.0 and 7.0. Closes gh-6164 --- spring-boot-actuator/pom.xml | 4 +- spring-boot-dependencies/pom.xml | 12 +- spring-boot-devtools/pom.xml | 4 +- spring-boot-docs/pom.xml | 4 +- spring-boot-samples/README.adoc | 8 +- spring-boot-samples/pom.xml | 2 + .../spring-boot-sample-tomcat-jsp/pom.xml | 1 + .../spring-boot-sample-tomcat-ssl/pom.xml | 2 +- .../spring-boot-sample-tomcat7-ssl/pom.xml | 57 ++++++++ .../ssl/SampleTomcatSslApplication.java | 29 ++++ .../tomcat/ssl/web/SampleController.java | 32 +++++ .../src/main/resources/application.properties | 4 + .../src/main/resources/sample.jks | Bin 0 -> 2264 bytes .../ssl/SampleTomcatSslApplicationTests.java | 51 +++++++ .../spring-boot-sample-tomcat80-ssl/pom.xml | 57 ++++++++ .../ssl/SampleTomcatSslApplication.java | 29 ++++ .../tomcat/ssl/web/SampleController.java | 32 +++++ .../src/main/resources/application.properties | 4 + .../src/main/resources/sample.jks | Bin 0 -> 2264 bytes .../ssl/SampleTomcatSslApplicationTests.java | 51 +++++++ .../spring-boot-starter-tomcat/pom.xml | 4 +- spring-boot-test/pom.xml | 4 +- spring-boot/pom.xml | 4 +- .../TomcatEmbeddedJSSEImplementation.java | 98 ------------- ...TomcatEmbeddedServletContainerFactory.java | 135 ++++++++++++++++-- .../boot/SpringApplicationTests.java | 6 +- ...tEmbeddedServletContainerFactoryTests.java | 5 +- ...tEmbeddedServletContainerFactoryTests.java | 36 +++-- 28 files changed, 521 insertions(+), 154 deletions(-) create mode 100644 spring-boot-samples/spring-boot-sample-tomcat7-ssl/pom.xml create mode 100644 spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/java/sample/tomcat/ssl/SampleTomcatSslApplication.java create mode 100644 spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/java/sample/tomcat/ssl/web/SampleController.java create mode 100644 spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/resources/application.properties create mode 100644 spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/resources/sample.jks create mode 100644 spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/test/java/sample/tomcat/ssl/SampleTomcatSslApplicationTests.java create mode 100644 spring-boot-samples/spring-boot-sample-tomcat80-ssl/pom.xml create mode 100644 spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/java/sample/tomcat/ssl/SampleTomcatSslApplication.java create mode 100644 spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/java/sample/tomcat/ssl/web/SampleController.java create mode 100644 spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/resources/application.properties create mode 100644 spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/resources/sample.jks create mode 100644 spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/test/java/sample/tomcat/ssl/SampleTomcatSslApplicationTests.java delete mode 100644 spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedJSSEImplementation.java diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml index 1b23af54caf..f7641cacbed 100644 --- a/spring-boot-actuator/pom.xml +++ b/spring-boot-actuator/pom.xml @@ -308,8 +308,8 @@ test - org.apache.tomcat.embed - tomcat-embed-logging-juli + org.apache.tomcat + tomcat-juli test diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index 56d1ff334a5..c277fc0af2b 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -173,7 +173,7 @@ 1.4.0 1.3 2.1.0.RELEASE - 8.0.33 + 8.5.3 1.3.22.Final 1.7 2.0 @@ -1314,11 +1314,6 @@ tomcat-embed-jasper ${tomcat.version} - - org.apache.tomcat.embed - tomcat-embed-logging-juli - ${tomcat.version} - org.apache.tomcat.embed tomcat-embed-websocket @@ -1334,6 +1329,11 @@ tomcat-jsp-api ${tomcat.version} + + org.apache.tomcat + tomcat-juli + ${tomcat.version} + org.apache.velocity velocity diff --git a/spring-boot-devtools/pom.xml b/spring-boot-devtools/pom.xml index 69468f65156..72c68b82cf5 100644 --- a/spring-boot-devtools/pom.xml +++ b/spring-boot-devtools/pom.xml @@ -118,8 +118,8 @@ test - org.apache.tomcat.embed - tomcat-embed-logging-juli + org.apache.tomcat + tomcat-juli test diff --git a/spring-boot-docs/pom.xml b/spring-boot-docs/pom.xml index 440ff6b884b..d0fc03f9385 100644 --- a/spring-boot-docs/pom.xml +++ b/spring-boot-docs/pom.xml @@ -300,8 +300,8 @@ true - org.apache.tomcat.embed - tomcat-embed-logging-juli + org.apache.tomcat + tomcat-juli true diff --git a/spring-boot-samples/README.adoc b/spring-boot-samples/README.adoc index 79cb2402759..590a0c437f6 100644 --- a/spring-boot-samples/README.adoc +++ b/spring-boot-samples/README.adoc @@ -193,7 +193,7 @@ The following sample applications are provided: | Embedded Tomcat | link:spring-boot-sample-tomcat-jsp[spring-boot-sample-tomcat-jsp] -| Web application that uses JSP templates with Tomcat 8 +| Web application that uses JSP templates with Tomcat | link:spring-boot-sample-tomcat-multi-connectors[spring-boot-sample-tomcat-multi-connectors] | Web application that uses Tomcat configured with multiple connectors @@ -204,6 +204,12 @@ The following sample applications are provided: | link:spring-boot-sample-tomcat7-jsp[spring-boot-sample-tomcat7-jsp] | Web application that uses JSP templates with Tomcat 7 +| link:spring-boot-sample-tomcat7-ssl[spring-boot-sample-tomcat7-ssl] +| Web application that uses Tomcat 7 configured with SSL + +| link:spring-boot-sample-tomcat80-ssl[spring-boot-sample-tomcat80-ssl] +| Web application that uses Tomcat 8.0 configured with SSL + | link:spring-boot-sample-traditional[spring-boot-sample-traditional] | Traditional WAR packaging (but also executable using `java -jar`) diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml index fbe02fd085a..95984aceb61 100644 --- a/spring-boot-samples/pom.xml +++ b/spring-boot-samples/pom.xml @@ -87,6 +87,8 @@ spring-boot-sample-tomcat-ssl spring-boot-sample-tomcat-multi-connectors spring-boot-sample-tomcat7-jsp + spring-boot-sample-tomcat7-ssl + spring-boot-sample-tomcat80-ssl spring-boot-sample-traditional spring-boot-sample-undertow spring-boot-sample-undertow-ssl diff --git a/spring-boot-samples/spring-boot-sample-tomcat-jsp/pom.xml b/spring-boot-samples/spring-boot-sample-tomcat-jsp/pom.xml index c09885658b7..0fe62952f92 100644 --- a/spring-boot-samples/spring-boot-sample-tomcat-jsp/pom.xml +++ b/spring-boot-samples/spring-boot-sample-tomcat-jsp/pom.xml @@ -19,6 +19,7 @@ ${basedir}/../.. / + 7.0.69 diff --git a/spring-boot-samples/spring-boot-sample-tomcat-ssl/pom.xml b/spring-boot-samples/spring-boot-sample-tomcat-ssl/pom.xml index c583d318682..ad943275324 100644 --- a/spring-boot-samples/spring-boot-sample-tomcat-ssl/pom.xml +++ b/spring-boot-samples/spring-boot-sample-tomcat-ssl/pom.xml @@ -8,7 +8,7 @@ 1.4.0.BUILD-SNAPSHOT spring-boot-sample-tomcat-ssl - Spring Boot Tomcat Sample + Spring Boot Tomcat SSL Sample Spring Boot Tomcat SSL Sample http://projects.spring.io/spring-boot/ diff --git a/spring-boot-samples/spring-boot-sample-tomcat7-ssl/pom.xml b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/pom.xml new file mode 100644 index 00000000000..8796da6189c --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-samples + 1.4.0.BUILD-SNAPSHOT + + spring-boot-sample-tomcat7-ssl + Spring Boot Tomcat 7 SSL Sample + Spring Boot Tomcat 7 SSL Sample + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + 7.0.69 + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework + spring-webmvc + + + org.apache.httpcomponents + httpclient + + + org.springframework.boot + spring-boot-starter-test + test + + + org.yaml + snakeyaml + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/java/sample/tomcat/ssl/SampleTomcatSslApplication.java b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/java/sample/tomcat/ssl/SampleTomcatSslApplication.java new file mode 100644 index 00000000000..32d2e6ed776 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/java/sample/tomcat/ssl/SampleTomcatSslApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2015 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 + * + * http://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 sample.tomcat.ssl; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SampleTomcatSslApplication { + + public static void main(String[] args) throws Exception { + SpringApplication.run(SampleTomcatSslApplication.class, args); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/java/sample/tomcat/ssl/web/SampleController.java b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/java/sample/tomcat/ssl/web/SampleController.java new file mode 100644 index 00000000000..7ca0d5ed01c --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/java/sample/tomcat/ssl/web/SampleController.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2016 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 + * + * http://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 sample.tomcat.ssl.web; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class SampleController { + + @GetMapping("/") + @ResponseBody + public String helloWorld() { + return "Hello, world"; + } + +} diff --git a/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/resources/application.properties new file mode 100644 index 00000000000..37199bfd256 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port = 8443 +server.ssl.key-store = classpath:sample.jks +server.ssl.key-store-password = secret +server.ssl.key-password = password diff --git a/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/resources/sample.jks b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/main/resources/sample.jks new file mode 100644 index 0000000000000000000000000000000000000000..6aa9a28053a591e41453e665e5024e8a8cb78b3d GIT binary patch literal 2264 zcmchYX*3iJ7sqE|hQS!q5Mv)4GM2$i#uAFqC`%7x7baWA*i&dRX>3`uq(XS?3XSYp z%38`&ib7E$8j~$cF^}gt?|I+noW8#w?uYxk=iGD8|K9Vzd#pVc0002(2k@T|2@MMI zqxqr2AhQO*TVi`j@((S;e;g;l$#dAA{>vf0kX$R(Qn4oKgGEYjZ5zti2dw?Z6A zh%LuFCNI?9o+Z1duJL-++e#cjO`zlK?u9s030=k_*wD1#-$FbIDRDnA^vo@fm( zzjt(3VJrGOr0iHXSTM|rYN#>RZ@Dp`PwB2zrDQffLvuoR2~V3ReYa0&vU^dXd8isV zsAf*@!8s%xBvHLseXn6f?1kefe(8uAmAbaF$x{Ykzb6c6jdUwY1$y4tFzsj7 zIghr!T#ODfu@Po!a29@kXQ8kY#(LE<0o7?7PQ|eMeY@Equ?R-6*f@Na3o&stDQ=6( zQzDSQhCnS(9Bu9W_~giknP0vECqUsr4_9y_}nEU`cy z4}dApnAip92wMwgzciAFpc3i}+-#Zlq+iF7d1y}d4Qsp8=%l1N8NIs161I`HmkcpQ zY4*CUCFJJf(2!M{`&qQ}3($KeTQ=)mMrBs`DOb;%Of0tC)9he_p~w&CO#DfCgx(%s z{@|D(brX_Gb}ZDLmGej*JgEl0Et>q~kgTXuJg-PwvRjNx8sBbIShxD=xOySzw{;^X zAvrh5HTg>Xq@<{#^!Kg}B?qz@b<{ebD)yaSf&RChBIJQo-?Ahzw@qopSe^e&>^IuU zydM4Y1_C&>k7u|}=; z63R7$H6zat=hNExxEwXu1fQ*ytuEkP!{w{|#6TIEq1#*ck=6_NM*ILF65tmD-O5&R zMI!-MT<3U~t@}(CN4@RlZ~1I>C=!ywF)dNI{VvH;5Y3(Z4jY^%_c&fsm4Q`<1g|qX z&!h29jXjVE3nJnet*L)XL?-8<>qDbVGP%i^NwOZfwWO7?Mr!X7 zl}sG@9S_5}}td}$xrWIYY=e(VVBiv%A+M-{M z!3_^Tc=pV?niT!{D`!{e@W;MvrZ(OER{x7itVAtwE~spPtPtma|J=5dv&_oE!5H#` zdgXJ;+gJ4hI}*9QX9jpL`Gb)yCe%1}t!&O-^sihyZys%%5uF~WhsR_w(q7;vV5d4P zr%ZUA2}kO+L^2ePTgGT9Ua71w<+)poSyjTdLq&xbUn`<6&SpwFp(HRHUyU6J3WZ_! zfztko79+94Tq%mTYj53(RYcL&1~5`I#+w3`(Q|r+P(aT z%?r(^?IWw~19CB&uvXf(f7&BnEE{zwK4piVU`I4j1j?v5d4N<7VUJ8nM`$7S*mfKR z#9-JzPRZ?{M!@L+0N^V)IyeeP2T|^UK|m0QD+Ibs!wEoml^N!YO#vW~j~jraX(0A3 z6Kux?IRLez`O^X;{!4g%BhcRn>^H*qKZ3*|{_YGuz)KCJcu;)DSES5D2tDE`C02YR0R%Vy1T7k|RQ;3g<0icA$AuP0pOvc~jGl zz+NeKv_FT_;GWK&8XlDUv&hv9kxg?@c!bu?83i=YQ$S!K09Y)Glg3Hz?@|)ZCBlVz zP8i}#XZkMoje3I=h&I!!s_m?Qi@1MR`yv7X*yEs47qOs^t^?&=;*IQ!q&)gq_Sx5* z?fhU8Q*PSe*w7y)FH#P!9R^Xw!lTT+zI39L<&8cViaj$A(Z2Cg7!{V?uuyi#vlNCg z40i}2ivw&y&1-&Nh&WMG`&aIt>)(#tKTJ}^@696Kw1-{IzSOTnFF+0@k$o3%ZHS;Q#;t literal 0 HcmV?d00001 diff --git a/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/test/java/sample/tomcat/ssl/SampleTomcatSslApplicationTests.java b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/test/java/sample/tomcat/ssl/SampleTomcatSslApplicationTests.java new file mode 100644 index 00000000000..f7b42c68a6f --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat7-ssl/src/test/java/sample/tomcat/ssl/SampleTomcatSslApplicationTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-2016 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 + * + * http://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 sample.tomcat.ssl; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@DirtiesContext +public class SampleTomcatSslApplicationTests { + + @LocalServerPort + private int port; + + @Test + public void testHome() throws Exception { + TestRestTemplate testRestTemplate = new TestRestTemplate(HttpClientOption.SSL); + ResponseEntity entity = testRestTemplate + .getForEntity("https://localhost:" + this.port, String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).isEqualTo("Hello, world"); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-tomcat80-ssl/pom.xml b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/pom.xml new file mode 100644 index 00000000000..4da6d54d885 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-samples + 1.4.0.BUILD-SNAPSHOT + + spring-boot-sample-tomcat-ssl + Spring Boot Tomcat 8.0 SSL Sample + Spring Boot Tomcat 8.0 SSL Sample + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + 8.0.33 + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework + spring-webmvc + + + org.apache.httpcomponents + httpclient + + + org.springframework.boot + spring-boot-starter-test + test + + + org.yaml + snakeyaml + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/java/sample/tomcat/ssl/SampleTomcatSslApplication.java b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/java/sample/tomcat/ssl/SampleTomcatSslApplication.java new file mode 100644 index 00000000000..32d2e6ed776 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/java/sample/tomcat/ssl/SampleTomcatSslApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2015 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 + * + * http://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 sample.tomcat.ssl; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SampleTomcatSslApplication { + + public static void main(String[] args) throws Exception { + SpringApplication.run(SampleTomcatSslApplication.class, args); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/java/sample/tomcat/ssl/web/SampleController.java b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/java/sample/tomcat/ssl/web/SampleController.java new file mode 100644 index 00000000000..7ca0d5ed01c --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/java/sample/tomcat/ssl/web/SampleController.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2016 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 + * + * http://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 sample.tomcat.ssl.web; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class SampleController { + + @GetMapping("/") + @ResponseBody + public String helloWorld() { + return "Hello, world"; + } + +} diff --git a/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/resources/application.properties new file mode 100644 index 00000000000..37199bfd256 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port = 8443 +server.ssl.key-store = classpath:sample.jks +server.ssl.key-store-password = secret +server.ssl.key-password = password diff --git a/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/resources/sample.jks b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/main/resources/sample.jks new file mode 100644 index 0000000000000000000000000000000000000000..6aa9a28053a591e41453e665e5024e8a8cb78b3d GIT binary patch literal 2264 zcmchYX*3iJ7sqE|hQS!q5Mv)4GM2$i#uAFqC`%7x7baWA*i&dRX>3`uq(XS?3XSYp z%38`&ib7E$8j~$cF^}gt?|I+noW8#w?uYxk=iGD8|K9Vzd#pVc0002(2k@T|2@MMI zqxqr2AhQO*TVi`j@((S;e;g;l$#dAA{>vf0kX$R(Qn4oKgGEYjZ5zti2dw?Z6A zh%LuFCNI?9o+Z1duJL-++e#cjO`zlK?u9s030=k_*wD1#-$FbIDRDnA^vo@fm( zzjt(3VJrGOr0iHXSTM|rYN#>RZ@Dp`PwB2zrDQffLvuoR2~V3ReYa0&vU^dXd8isV zsAf*@!8s%xBvHLseXn6f?1kefe(8uAmAbaF$x{Ykzb6c6jdUwY1$y4tFzsj7 zIghr!T#ODfu@Po!a29@kXQ8kY#(LE<0o7?7PQ|eMeY@Equ?R-6*f@Na3o&stDQ=6( zQzDSQhCnS(9Bu9W_~giknP0vECqUsr4_9y_}nEU`cy z4}dApnAip92wMwgzciAFpc3i}+-#Zlq+iF7d1y}d4Qsp8=%l1N8NIs161I`HmkcpQ zY4*CUCFJJf(2!M{`&qQ}3($KeTQ=)mMrBs`DOb;%Of0tC)9he_p~w&CO#DfCgx(%s z{@|D(brX_Gb}ZDLmGej*JgEl0Et>q~kgTXuJg-PwvRjNx8sBbIShxD=xOySzw{;^X zAvrh5HTg>Xq@<{#^!Kg}B?qz@b<{ebD)yaSf&RChBIJQo-?Ahzw@qopSe^e&>^IuU zydM4Y1_C&>k7u|}=; z63R7$H6zat=hNExxEwXu1fQ*ytuEkP!{w{|#6TIEq1#*ck=6_NM*ILF65tmD-O5&R zMI!-MT<3U~t@}(CN4@RlZ~1I>C=!ywF)dNI{VvH;5Y3(Z4jY^%_c&fsm4Q`<1g|qX z&!h29jXjVE3nJnet*L)XL?-8<>qDbVGP%i^NwOZfwWO7?Mr!X7 zl}sG@9S_5}}td}$xrWIYY=e(VVBiv%A+M-{M z!3_^Tc=pV?niT!{D`!{e@W;MvrZ(OER{x7itVAtwE~spPtPtma|J=5dv&_oE!5H#` zdgXJ;+gJ4hI}*9QX9jpL`Gb)yCe%1}t!&O-^sihyZys%%5uF~WhsR_w(q7;vV5d4P zr%ZUA2}kO+L^2ePTgGT9Ua71w<+)poSyjTdLq&xbUn`<6&SpwFp(HRHUyU6J3WZ_! zfztko79+94Tq%mTYj53(RYcL&1~5`I#+w3`(Q|r+P(aT z%?r(^?IWw~19CB&uvXf(f7&BnEE{zwK4piVU`I4j1j?v5d4N<7VUJ8nM`$7S*mfKR z#9-JzPRZ?{M!@L+0N^V)IyeeP2T|^UK|m0QD+Ibs!wEoml^N!YO#vW~j~jraX(0A3 z6Kux?IRLez`O^X;{!4g%BhcRn>^H*qKZ3*|{_YGuz)KCJcu;)DSES5D2tDE`C02YR0R%Vy1T7k|RQ;3g<0icA$AuP0pOvc~jGl zz+NeKv_FT_;GWK&8XlDUv&hv9kxg?@c!bu?83i=YQ$S!K09Y)Glg3Hz?@|)ZCBlVz zP8i}#XZkMoje3I=h&I!!s_m?Qi@1MR`yv7X*yEs47qOs^t^?&=;*IQ!q&)gq_Sx5* z?fhU8Q*PSe*w7y)FH#P!9R^Xw!lTT+zI39L<&8cViaj$A(Z2Cg7!{V?uuyi#vlNCg z40i}2ivw&y&1-&Nh&WMG`&aIt>)(#tKTJ}^@696Kw1-{IzSOTnFF+0@k$o3%ZHS;Q#;t literal 0 HcmV?d00001 diff --git a/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/test/java/sample/tomcat/ssl/SampleTomcatSslApplicationTests.java b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/test/java/sample/tomcat/ssl/SampleTomcatSslApplicationTests.java new file mode 100644 index 00000000000..f7b42c68a6f --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-tomcat80-ssl/src/test/java/sample/tomcat/ssl/SampleTomcatSslApplicationTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-2016 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 + * + * http://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 sample.tomcat.ssl; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@DirtiesContext +public class SampleTomcatSslApplicationTests { + + @LocalServerPort + private int port; + + @Test + public void testHome() throws Exception { + TestRestTemplate testRestTemplate = new TestRestTemplate(HttpClientOption.SSL); + ResponseEntity entity = testRestTemplate + .getForEntity("https://localhost:" + this.port, String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).isEqualTo("Hello, world"); + } + +} diff --git a/spring-boot-starters/spring-boot-starter-tomcat/pom.xml b/spring-boot-starters/spring-boot-starter-tomcat/pom.xml index 50ccbc4d84b..7f8388079ec 100644 --- a/spring-boot-starters/spring-boot-starter-tomcat/pom.xml +++ b/spring-boot-starters/spring-boot-starter-tomcat/pom.xml @@ -28,8 +28,8 @@ tomcat-embed-el - org.apache.tomcat.embed - tomcat-embed-logging-juli + org.apache.tomcat + tomcat-juli org.apache.tomcat.embed diff --git a/spring-boot-test/pom.xml b/spring-boot-test/pom.xml index ff648694f31..067563b234e 100644 --- a/spring-boot-test/pom.xml +++ b/spring-boot-test/pom.xml @@ -112,8 +112,8 @@ test - org.apache.tomcat.embed - tomcat-embed-logging-juli + org.apache.tomcat + tomcat-juli test diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index 25648b99778..c90fe9e3973 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -110,8 +110,8 @@ true - org.apache.tomcat.embed - tomcat-embed-logging-juli + org.apache.tomcat + tomcat-juli true diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedJSSEImplementation.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedJSSEImplementation.java deleted file mode 100644 index 6681da0c4e4..00000000000 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedJSSEImplementation.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012-2016 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 - * - * http://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.context.embedded.tomcat; - -import java.io.IOException; -import java.security.KeyStore; - -import org.apache.tomcat.util.net.AbstractEndpoint; -import org.apache.tomcat.util.net.SSLUtil; -import org.apache.tomcat.util.net.ServerSocketFactory; -import org.apache.tomcat.util.net.jsse.JSSEImplementation; -import org.apache.tomcat.util.net.jsse.JSSESocketFactory; - -import org.springframework.boot.context.embedded.SslStoreProvider; - -/** - * {@link JSSEImplementation} for embedded Tomcat that supports {@link SslStoreProvider}. - * - * @author Phillip Webb - * @author Venil Noronha - * @since 1.4.0 - */ -public class TomcatEmbeddedJSSEImplementation extends JSSEImplementation { - - @Override - public ServerSocketFactory getServerSocketFactory(AbstractEndpoint endpoint) { - return new SocketFactory(endpoint); - } - - @Override - public SSLUtil getSSLUtil(AbstractEndpoint endpoint) { - return new SocketFactory(endpoint); - } - - /** - * {@link JSSESocketFactory} that supports {@link SslStoreProvider}. - */ - static class SocketFactory extends JSSESocketFactory { - - private final SslStoreProvider sslStoreProvider; - - SocketFactory(AbstractEndpoint endpoint) { - super(endpoint); - this.sslStoreProvider = (SslStoreProvider) endpoint - .getAttribute("sslStoreProvider"); - } - - @Override - protected KeyStore getKeystore(String type, String provider, String pass) - throws IOException { - if (this.sslStoreProvider != null) { - try { - KeyStore store = this.sslStoreProvider.getKeyStore(); - if (store != null) { - return store; - } - } - catch (Exception ex) { - throw new IOException(ex); - } - } - return super.getKeystore(type, provider, pass); - } - - @Override - protected KeyStore getTrustStore(String keystoreType, String keystoreProvider) - throws IOException { - if (this.sslStoreProvider != null) { - try { - KeyStore store = this.sslStoreProvider.getTrustStore(); - if (store != null) { - return store; - } - } - catch (Exception ex) { - throw new IOException(ex); - } - } - return super.getTrustStore(keystoreType, keystoreProvider); - } - - } - -} diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index 96477db2e4c..e3e40a7688c 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -16,12 +16,19 @@ package org.springframework.boot.context.embedded.tomcat; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; import java.nio.charset.Charset; +import java.security.KeyStore; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -48,11 +55,13 @@ import org.apache.catalina.session.ManagerBase; import org.apache.catalina.session.StandardManager; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.Tomcat.FixContextListener; +import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory; import org.apache.coyote.AbstractProtocol; import org.apache.coyote.ProtocolHandler; import org.apache.coyote.http11.AbstractHttp11JsseProtocol; import org.apache.coyote.http11.AbstractHttp11Protocol; import org.apache.coyote.http11.Http11NioProtocol; +import org.apache.tomcat.util.net.SSLHostConfig; import org.springframework.beans.BeanUtils; import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory; @@ -301,7 +310,7 @@ public class TomcatEmbeddedServletContainerFactory Compression compression = getCompression(); protocol.setCompression("on"); protocol.setCompressionMinSize(compression.getMinResponseSize()); - protocol.setCompressableMimeTypes( + protocol.setCompressableMimeType( StringUtils.arrayToCommaDelimitedString(compression.getMimeTypes())); if (getCompression().getExcludedUserAgents() != null) { protocol.setNoCompressionUserAgents( @@ -323,13 +332,33 @@ public class TomcatEmbeddedServletContainerFactory protocol.setKeystorePass(ssl.getKeyStorePassword()); protocol.setKeyPass(ssl.getKeyPassword()); protocol.setKeyAlias(ssl.getKeyAlias()); - protocol.setCiphers(StringUtils.arrayToCommaDelimitedString(ssl.getCiphers())); + String ciphers = StringUtils.arrayToCommaDelimitedString(ssl.getCiphers()); + protocol.setCiphers(StringUtils.hasText(ciphers) ? ciphers : null); if (ssl.getEnabledProtocols() != null) { - protocol.setProperty("sslEnabledProtocols", - StringUtils.arrayToCommaDelimitedString(ssl.getEnabledProtocols())); + try { + for (SSLHostConfig sslHostConfig : protocol.findSslHostConfigs()) { + sslHostConfig.setProtocols(StringUtils + .arrayToCommaDelimitedString(ssl.getEnabledProtocols())); + } + } + catch (NoSuchMethodError ex) { + // Tomcat 8.0.x or earlier + Assert.isTrue( + protocol.setProperty("sslEnabledProtocols", + StringUtils.arrayToCommaDelimitedString( + ssl.getEnabledProtocols())), + "Failed to set sslEnabledProtocols"); + } } if (getSslStoreProvider() != null) { - configureSslStoreProvider(protocol, getSslStoreProvider()); + TomcatURLStreamHandlerFactory instance = TomcatURLStreamHandlerFactory + .getInstance(); + instance.addUserFactory( + new SslStoreProviderUrlStreamHandlerFactory(getSslStoreProvider())); + protocol.setKeystoreFile( + SslStoreProviderUrlStreamHandlerFactory.KEY_STORE_URL); + protocol.setTruststoreFile( + SslStoreProviderUrlStreamHandlerFactory.TRUST_STORE_URL); } else { configureSslKeyStore(protocol, ssl); @@ -350,10 +379,6 @@ public class TomcatEmbeddedServletContainerFactory SslStoreProvider sslStoreProvider) { Assert.isInstanceOf(Http11NioProtocol.class, protocol, "SslStoreProvider can only be used with Http11NioProtocol"); - ((Http11NioProtocol) protocol).getEndpoint().setAttribute("sslStoreProvider", - sslStoreProvider); - protocol.setSslImplementationName( - TomcatEmbeddedJSSEImplementation.class.getName()); } private void configureSslKeyStore(AbstractHttp11JsseProtocol protocol, Ssl ssl) { @@ -677,6 +702,89 @@ public class TomcatEmbeddedServletContainerFactory return this.uriEncoding; } + /** + * A {@link URLStreamHandlerFactory} that provides a {@link URLStreamHandler} for + * accessing an {@link SslStoreProvider}'s key store and trust store from a URL. + */ + private static final class SslStoreProviderUrlStreamHandlerFactory + implements URLStreamHandlerFactory { + + private static final String PROTOCOL = "springbootssl"; + + private static final String KEY_STORE_PATH = "keyStore"; + + private static final String KEY_STORE_URL = PROTOCOL + ":" + KEY_STORE_PATH; + + private static final String TRUST_STORE_PATH = "trustStore"; + + private static final String TRUST_STORE_URL = PROTOCOL + ":" + TRUST_STORE_PATH; + + private final SslStoreProvider sslStoreProvider; + + private SslStoreProviderUrlStreamHandlerFactory( + SslStoreProvider sslStoreProvider) { + this.sslStoreProvider = sslStoreProvider; + } + + @Override + public URLStreamHandler createURLStreamHandler(String protocol) { + if (PROTOCOL.equals(protocol)) { + return new URLStreamHandler() { + + @Override + protected URLConnection openConnection(URL url) throws IOException { + try { + if (KEY_STORE_PATH.equals(url.getPath())) { + return new KeyStoreUrlConnection(url, + SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider + .getKeyStore()); + } + if (TRUST_STORE_PATH.equals(url.getPath())) { + return new KeyStoreUrlConnection(url, + SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider + .getTrustStore()); + } + } + catch (Exception ex) { + throw new IOException(ex); + } + throw new IOException("Invalid path: " + url.getPath()); + } + }; + } + return null; + } + + private static final class KeyStoreUrlConnection extends URLConnection { + + private final KeyStore keyStore; + + private KeyStoreUrlConnection(URL url, KeyStore keyStore) { + super(url); + this.keyStore = keyStore; + } + + @Override + public void connect() throws IOException { + + } + + @Override + public InputStream getInputStream() throws IOException { + + try { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + this.keyStore.store(stream, new char[0]); + return new ByteArrayInputStream(stream.toByteArray()); + } + catch (Exception ex) { + throw new IOException(ex); + } + } + + } + } + private static class TomcatErrorPage { private static final String ERROR_PAGE_CLASS = "org.apache.tomcat.util.descriptor.web.ErrorPage"; @@ -752,8 +860,7 @@ public class TomcatEmbeddedServletContainerFactory */ private static class StoreMergedWebXmlListener implements LifecycleListener { - @SuppressWarnings("deprecation") - private final String MERGED_WEB_XML = org.apache.tomcat.util.scan.Constants.MERGED_WEB_XML; + private static final String MERGED_WEB_XML = "org.apache.tomcat.util.scan.MergedWebXml"; @Override public void lifecycleEvent(LifecycleEvent event) { @@ -764,8 +871,10 @@ public class TomcatEmbeddedServletContainerFactory private void onStart(Context context) { ServletContext servletContext = context.getServletContext(); - if (servletContext.getAttribute(this.MERGED_WEB_XML) == null) { - servletContext.setAttribute(this.MERGED_WEB_XML, getEmptyWebXml()); + if (servletContext + .getAttribute(StoreMergedWebXmlListener.MERGED_WEB_XML) == null) { + servletContext.setAttribute(StoreMergedWebXmlListener.MERGED_WEB_XML, + getEmptyWebXml()); } TomcatResources.get(context).addClasspathResources(); } diff --git a/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java b/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java index c80dc0c2a96..84608f01a8f 100644 --- a/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java @@ -40,7 +40,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.beans.factory.support.DefaultBeanNameGenerator; import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; -import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory; +import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; import org.springframework.boot.context.event.ApplicationPreparedEvent; import org.springframework.boot.context.event.ApplicationReadyEvent; @@ -971,8 +971,8 @@ public class SpringApplicationTests { static class ExampleWebConfig { @Bean - public JettyEmbeddedServletContainerFactory container() { - return new JettyEmbeddedServletContainerFactory(0); + public TomcatEmbeddedServletContainerFactory container() { + return new TomcatEmbeddedServletContainerFactory(0); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java index faede699dde..f9cd1df7187 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java @@ -55,6 +55,7 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.InputStreamFactory; import org.apache.http.client.protocol.HttpClientContext; @@ -124,6 +125,8 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { @BeforeClass @AfterClass public static void uninstallUrlStreamHandlerFactory() { + ReflectionTestUtils.setField(TomcatURLStreamHandlerFactory.class, "instance", + null); ReflectionTestUtils.setField(URL.class, "factory", null); } @@ -589,7 +592,7 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); } - private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyStore) { + protected Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyStore) { return getSsl(clientAuth, keyPassword, keyStore, null, null, null); } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java index 2b57c02b096..8695ef70993 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java @@ -38,7 +38,7 @@ import org.apache.catalina.Wrapper; import org.apache.catalina.connector.Connector; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.valves.RemoteIpValve; -import org.apache.coyote.http11.AbstractHttp11JsseProtocol; +import org.apache.tomcat.util.net.SSLHostConfig; import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -266,16 +266,14 @@ public class TomcatEmbeddedServletContainerFactoryTests Tomcat tomcat = getTomcat(factory); Connector connector = tomcat.getConnector(); - AbstractHttp11JsseProtocol jsseProtocol = (AbstractHttp11JsseProtocol) connector - .getProtocolHandler(); - assertThat(jsseProtocol.getCiphers()).isEqualTo("ALPHA,BRAVO,CHARLIE"); + SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler() + .findSslHostConfigs(); + assertThat(sslHostConfigs[0].getCiphers()).isEqualTo("ALPHA:BRAVO:CHARLIE"); } @Test public void sslEnabledMultipleProtocolsConfiguration() throws Exception { - Ssl ssl = new Ssl(); - ssl.setKeyStore("test.jks"); - ssl.setKeyStorePassword("secret"); + Ssl ssl = getSsl(null, "password", "src/test/resources/test.jks"); ssl.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" }); ssl.setCiphers(new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO" }); @@ -284,21 +282,20 @@ public class TomcatEmbeddedServletContainerFactoryTests this.container = factory .getEmbeddedServletContainer(sessionServletRegistration()); + this.container.start(); Tomcat tomcat = ((TomcatEmbeddedServletContainer) this.container).getTomcat(); Connector connector = tomcat.getConnector(); - AbstractHttp11JsseProtocol jsseProtocol = (AbstractHttp11JsseProtocol) connector - .getProtocolHandler(); - assertThat(jsseProtocol.getSslProtocol()).isEqualTo("TLS"); - assertThat(jsseProtocol.getProperty("sslEnabledProtocols")) - .isEqualTo("TLSv1.1,TLSv1.2"); + SSLHostConfig sslHostConfig = connector.getProtocolHandler() + .findSslHostConfigs()[0]; + assertThat(sslHostConfig.getSslProtocol()).isEqualTo("TLS"); + assertThat(sslHostConfig.getEnabledProtocols()) + .containsExactlyInAnyOrder("TLSv1.1", "TLSv1.2"); } @Test public void sslEnabledProtocolsConfiguration() throws Exception { - Ssl ssl = new Ssl(); - ssl.setKeyStore("test.jks"); - ssl.setKeyStorePassword("secret"); + Ssl ssl = getSsl(null, "password", "src/test/resources/test.jks"); ssl.setEnabledProtocols(new String[] { "TLSv1.2" }); ssl.setCiphers(new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO" }); @@ -310,10 +307,11 @@ public class TomcatEmbeddedServletContainerFactoryTests Tomcat tomcat = ((TomcatEmbeddedServletContainer) this.container).getTomcat(); Connector connector = tomcat.getConnector(); - AbstractHttp11JsseProtocol jsseProtocol = (AbstractHttp11JsseProtocol) connector - .getProtocolHandler(); - assertThat(jsseProtocol.getSslProtocol()).isEqualTo("TLS"); - assertThat(jsseProtocol.getProperty("sslEnabledProtocols")).isEqualTo("TLSv1.2"); + this.container.start(); + SSLHostConfig sslHostConfig = connector.getProtocolHandler() + .findSslHostConfigs()[0]; + assertThat(sslHostConfig.getSslProtocol()).isEqualTo("TLS"); + assertThat(sslHostConfig.getEnabledProtocols()).containsExactly("TLSv1.2"); } @Test