Spring application and external tomcat server HTTP2 - spring-boot

When I deploy a spring boot application on an external tomcat server, do I need to configure HTTP2 on the tomcat server as well my spring boot application? I am a bit confused here about how the communication occurs when I call my spring application deployed inside of Tomcat via the browser or any other client say, Postman.
I have enabled HTTP2 on Tomcat and verified the same:
0:0:0:0:0:0:0:1 - - [08/Jan/2023:18:28:44 +0530] "GET / HTTP/2.0" 200 11408
0:0:0:0:0:0:0:1 - - [08/Jan/2023:18:28:44 +0530] "GET /tomcat.svg HTTP/2.0" 200 68761
0:0:0:0:0:0:0:1 - - [08/Jan/2023:18:28:44 +0530] "GET /tomcat.css HTTP/2.0" 200 5895
and I have configured my spring boot application to use HTTP2 as well using the steps mentioned in this link.
When I am calling my RestController deployed in the external tomcat, I am still getting HTTP 1.1
127.0.0.1 - - [08/Jan/2023:23:41:26 +0530] "HEAD /demo-0.0.1-SNAPSHOT/ HTTP/1.1" 200 -
127.0.0.1 - - [08/Jan/2023:23:41:51 +0530] "HEAD /demo-0.0.1-SNAPSHOT/getMessage HTTP/1.1" 200 -
where demo-0.0.1-SNAPSHOT is the deployed artifact.
I verified the same using curl
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 41
Date: Sun, 08 Jan 2023 18:11:51 GMT
What am I missing here?
My application.properties file looks like:
# configuring SSL
server.port=8443
server.ssl.key-store-type=pkcs12
server.ssl.key-store=classpath:springboot.p12
server.ssl.key-store-password=password
server.ssl.key-alias=springboot
# enabling http2
server.http2.enabled=true
and I have created the Keystore correctly using the following command:
keytool -genkeypair -alias springboot -keyalg RSA -keysize 4096 -storetype PKCS12 -keystore springboot.p12 -validity 3650 -storepass password
EDIT 1:
Spring Boot version - 2.7.2
Tomcat server - 9.0.70
In my server.xml, I have commented and edited the following Connector:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200" SSLEnabled="true">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeystoreFile="ssl/tomcat.jks"
certificateKeyAlias="tomcat"
certificateKeystorePassword="password"
type="RSA" />
</SSLHostConfig>
</Connector>
which has helped me enable TLS as well as HTTP2 both on Tomcat. The problem is when I am deploying a spring boot application and making rest calls to that application's RestController, I am getting HTTP1.1 response. Making calls to Tomcat webservices is giving correct HTTP2 response.

Tomcat as standalone sever has by default in it's sever.xml disabled the connector for http 2.
Spring Boot 2, up to Tomcat 9
If this is a spring boot 2 deployed as war application then this could be using up to Tomcat 9.
You must find your Tomcat 9 (Server.xml) connector for http2 under the deployed server conf directory and uncomment this connector, while also providing the necessary certificate files.
You need to uncomment the
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true" >
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
certificateFile="conf/localhost-rsa-cert.pem"
certificateChainFile="conf/localhost-rsa-chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
Spring Boot 3, Tomcat 10 or later
In case you have a spring boot 3 deployed as war application then this should be using Tomcat 10 or later.
You must find your Tomcat 10 (Server.xml) connector for http2 under the deployed server conf directory and uncomment while also providing the necessary certificate file.
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
type="RSA" />
</SSLHostConfig>
</Connector>

I found the solution. While deploying a spring boot application on external tomcat there is no need to specify Server SSL and HTTP2 parameters in the spring properties file as Tomcat will handle all the HTTPS requests. I was trying to mix 2 things.
Configuring the Spring Boot application to support HTTP2 will work if we are deploying using an embedded Tomcat server and I was able to verify that with Chrome browser.
As of writing this post, Postman still doesn't support HTTP2 requests, hence, I was seeing HTTP 1.1 protocol in the Tomcat access log. The same thing I believe is the issue with curl request. As my certificate is self-signed, I am using options -k and -sI. Maybe that's the reason, I am getting the response :
HTTP/1.1 200
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 10 Jan 2023 18:09:29 GMT
when running curl -k -sI https://localhost:8443. I will figure out why I am getting HTTP 1.1 and update it here.
Sharing this answer to help anyone coming across this question next time.

Related

How to resolve 502 and 503 errors with tomcat and springboot

We are constantly getting 502 and 503 errors during load test. 10% errors during the test and all of them are 502 and 503. We are using apache webserver and tomcat 9 as application server with springboot as framework. Any specific configuration to be added to avoid these errors? Please let me know. PFB the tomcat connector configurations:
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
maxHttpHeaderSize="65536"
maxPostSize="6291456"
maxConnections="1500"
maxThreads="1500"
redirectPort="8443"

Configure SSL in blueprint for CXF

I have an existing application deployed to Apache Karaf OSGi container.
The application bundles implement SOAP and REST web services using Apache CXF, configured by blueprint.xml files that look like this:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd
http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd
http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0 http://aries.apache.org/schemas/blueprint-ext/blueprint-ext.xsd">
<jaxws:endpoint id="bundle1-server" implementor="com.myapp.Bundle1ServiceImpl" endpointName="s:Bundle1Port"
serviceName="s:Bundle1Service" address="http://0.0.0.0:9080/SoapContext/Bundle1Port" wsdlLocation="wsdl/Bundle1Service.wsdl" xmlns:s="http://com.myapp/services/bundle1service">
</jaxws:endpoint>
</blueprint>
When the endpoint starts, I can see this in the log:
INFO | org.apache.cxf.endpoint.ServerImpl | | org.apache.cxf.endpoint.ServerImpl - initDestination - 85 | 109 - org.apache.cxf.cxf-core - 3.1.9 | Setting the server's publish address to be http://0.0.0.0:9080/SoapContext/Bundle1Port
INFO  | org.eclipse.jetty.server.ServerConnector |  | org.eclipse.jetty.server.AbstractConnector - doStart -  266 | 204 - org.eclipse.jetty.util - 9.2.15.v20160210 | Started ServerConnector#30394ac6{HTTP/1.1}{0.0.0.0:9080}
The CXF uses Jetty to receive the incoming HTTP requests (there is a cxf-rt-transports-http-jetty dependency in the pom.xml).
I want to switch the web services from http to https.
When I change the port number in the blueprint.xml, the web service is indeed reachable at the new port.
However, changing the URL scheme from http to https (http://:9080 to https://:9443) results in an error:
org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to initialize bean bundle1-server
...
Caused by: java.io.IOException: Protocol mismatch for port 9443: engine's protocol is http, the url protocol is https
at org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory.createJettyHTTPServerEngine(JettyHTTPServerEngineFactory.java:277)
Obviously, I also need to specify the server certificate and the CA certificate. I have tried to add the following:
<httpj:engine-factory bus="cxf">
<httpj:engine port="9443">
<httpj:tlsServerParameters>
<sec:keyManagers keyPassword="changeit">
<sec:keyStore type="JKS" password="changeit"
file="/path-to-certificates/keystore.ks"/>
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore type="JKS" password="password"
file="/path-to-certificates/truststore.ks"/>
</sec:trustManagers>
<sec:clientAuthentication want="false" required="false"/>
</httpj:tlsServerParameters>
</httpj:engine>
</httpj:engine-factory>
But now I get:
org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to load class org.eclipse.jetty.server.Connector from recipe MapRecipe[name='#recipe-85']
...
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.server.Connector not found by Bundle1 [255]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1574)[org.apache.felix.framework-5.4.0.jar:]
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:79)[org.apache.felix.framework-5.4.0.jar:]
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)[org.apache.felix.framework-5.4.0.jar:]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)[:1.8.0_262]
at org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1925)[org.apache.felix.framework-5.4.0.jar:]
at org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:978)[org.apache.felix.framework-5.4.0.jar:]
at org.apache.aries.blueprint.container.BlueprintContainerImpl.loadClass(BlueprintContainerImpl.java:467)[13:org.apache.aries.blueprint.core:1.6.1]
at org.apache.aries.blueprint.container.BlueprintRepository.loadClass(BlueprintRepository.java:419)[13:org.apache.aries.blueprint.core:1.6.1]
at org.apache.aries.blueprint.container.GenericType.parse(GenericType.java:135)[13:org.apache.aries.blueprint.core:1.6.1]
at org.apache.aries.blueprint.di.AbstractRecipe.doLoadType(AbstractRecipe.java:168)[13:org.apache.aries.blueprint.core:1.6.1]
What am I missing here?
Update: I also tried to configure SSL globally for the whole Karaf server by editing etc/org.ops4j.pax.web.cfg to include
org.osgi.service.http.secure.enabled=true
org.ops4j.pax.web.ssl.keystore=/path-to-keystore.ks
org.ops4j.pax.web.ssl.password=changeit
org.ops4j.pax.web.ssl.keypassword=changeit
org.osgi.service.http.port.secure=8443
Then I can see in the logs
INFO | org.ops4j.pax.web.service.jetty.internal.JettyServerImpl | | org.ops4j.pax.web.service.jetty.internal.JettyServerImpl - addConnector - 226 | 222 - org.ops4j.pax.web.pax-web-jetty - 4.2.6 | Pax Web available at [0.0.0.0]:[8443]
INFO | org.eclipse.jetty.server.ServerConnector | | org.eclipse.jetty.server.AbstractConnector - doStart - 266 | 204 - org.eclipse.jetty.util - 9.2.15.v20160210 | Started secureDefault#3bae4ef2{SSL-http/1.1}{0.0.0.0:8443}
..
Caused by: java.io.IOException: Protocol mismatch for port 8443: engine's protocol is http, the url protocol is https
Which is really confusing...
I have fixed the ClassNotFoundException by adding org.eclipse.jetty.server to Import-Package in META-INF/MANIFEST.MF
However, I have read this: "I strongly discourage people from configuring the jetty servers in their blueprint files" http://servicemix.396122.n5.nabble.com/servicemix-5-4-0-cxf-jetty-blueprint-issue-td5722268.html
So maybe I should still try to fix the latter (global) config if possible.

IBM WebSphere Liberty working with IHS Server Problems with Certificate(s)

I have a liberty server and an IHS server (both on different hosts). This is on rhel7.
I've followed a number of guides that I found that walk thru the setup of keystores and sharing of certs but still run into issues. For reference, I tried the methods detailed https://jazz.net/wiki/bin/view/Deployment/CreateIHSPLUGINFORLIBERTYPROFILE and https://www.ibm.com/support/knowledgecenter/en/SSEQTJ_9.0.5/com.ibm.websphere.ihs.doc/ihs/tihs_install_config_liberty.html.
A quick summary of what I have done this past attempt... On the liberty server I added the following to my server.xml to add a plugin include (to keep things easier to read):
<include location="${server.config.dir}/plugin-join-include.xml" />
And the plugin-join-include.xml:
<featureManager>
<feature>ssl-1.0</feature>
</featureManager>
<keyStore id="libertyKey" password="xxxx"
location="${server.config.dir}/resources/security/libkey.jks"/>
<pluginConfiguration webserverPort="10500" webserverSecurePort="10447"
pluginInstallRoot="/opt/IBM/wasadmin/Plugins"
sslKeyRingLocation="/opt/IBM/wasadmin/Plugins/config/webserver1/plugin-key.kdb"
sslStashFileLocation="/opt/IBM/wasadmin/Plugins/config/webserver1/plugin-key.sth"
sslCertlabel="libertyKey"/>
On my IHS server the path for the root Plugin directory is as indicated above in the file at /opt/IBM/wasadmin/Plugins and the plugin-key.kdb and plugin-key.sth are located in the locations listed above.
I reboot the liberty server and it generated the plugin-cfg.xml in the logs/state directory:
<?xml version="1.0" encoding="UTF-8"?><!--HTTP server plugin config file for app generated on 2020.03.04 at 12:32:02 UTC-->
<Config ASDisableNagle="false" AcceptAllContent="false" AppServerPortPreference="HostHeader" ChunkedResponse="false" ConfigHash="1077723051" FIPSEnable="false" IISDisableNagle="false" IISPluginPriority="High" IgnoreDNSFailures="false" RefreshInterval="60" ResponseChunkSize="64" SSLConsolidate="false" TrustedProxyEnable="false" VHostMatchingCompat="false">
<Log LogLevel="Error" Name="/opt/IBM/wasadmin/Plugins/logs/webserver1/http_plugin.log"/>
<Property Name="ESIEnable" Value="true"/>
<Property Name="ESIMaxCacheSize" Value="1024"/>
<Property Name="ESIInvalidationMonitor" Value="false"/>
<Property Name="ESIEnableToPassCookies" Value="false"/>
<Property Name="PluginInstallRoot" Value="/opt/IBM/wasadmin/Plugins"/>
<!-- Configuration generated using httpEndpointRef=defaultHttpEndpoint-->
<!-- The default_host contained only aliases for endpoint defaultHttpEndpoint.
The generated VirtualHostGroup will contain only configured web server ports:
webserverPort=10500
webserverSecurePort=10447 -->
<VirtualHostGroup Name="default_host">
<VirtualHost Name="*:10500"/>
<VirtualHost Name="*:10447"/>
</VirtualHostGroup>
<ServerCluster CloneSeparatorChange="false" GetDWLMTable="false" IgnoreAffinityRequests="true" LoadBalance="Round Robin" Name="affms_default_node_Cluster" PostBufferSize="0" PostSizeLimit="-1" RemoveSpecialHeaders="true" RetryInterval="60" ServerIOTimeoutRetry="-1">
<Server CloneID="412b3187-16c4-41b0-86e8-1e327c1c6b1b" ConnectTimeout="5" ExtendedHandshake="false" LoadBalanceWeight="20" MaxConnections="-1" Name="default_node_affms" ServerIOTimeout="900" WaitForContinue="false">
<Transport Hostname="libertyhost" Port="10500" Protocol="http"/>
<Transport Hostname="libertyhost" Port="10447" Protocol="https">
<Property Name="keyring" Value="/opt/IBM/wasadmin/Plugins/config/webserver1/plugin-key.kdb"/>
<Property Name="stashfile" Value="/opt/IBM/wasadmin/Plugins/config/webserver1/plugin-key.sth"/>
<Property Name="certLabel" Value="libertyKey"/>
</Transport>
</Server>
<PrimaryServers>
<Server Name="default_node_app"/>
</PrimaryServers>
</ServerCluster>
<UriGroup Name="default_host_app_default_node_Cluster_URIs">
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/app/ui/*"/>
<Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/adminCenter/*"/>
</UriGroup>
<Route ServerCluster="app_default_node_Cluster" UriGroup="default_host_app_default_node_Cluster_URIs" VirtualHostGroup="default_host"/>
I copy the plugin-cfg.xml over to the IHS server at /opt/IBM/wasadmin/Plugins/config/webserver1/plugin-cfg.xml
The plugin stuff works only the SSL portion between IHS and the app server give me issues.
On the IHS server I have created the plugin-key.kdb keystore with stash plugin-key.sth and imported the cert I extracted from the liberty server /opt/IBM/wlp/usr/servers/app/resources/security/key.p12 the default personal cert and copy it to the IHS server and add the default liberty cert to the plugin-key.kdb keystore.
At the bottom of the httpd.conf is:
LoadModule was_ap22_module /opt/IBM/wasadmin/Plugins/bin/64bits/mod_was_ap22_http.so
WebSpherePluginConfig /opt/IBM/wasadmin/Plugins/config/webserver1/plugin-cfg.xml
I bounce the apachectl and go to the url for the application on port 8443 https://hostname:8443/app/ui and get a "500 Internal Server Error".
The http_plugin.log plugin logs show:
[04/Mar/2020:18:23:48.31652] 00002f26 3cff9700 - ERROR: lib_stream: openStream: Failed in r_gsk_secure_soc_init: GSK_ERROR_BAD_CERT(gsk rc = 414) PARTNER CERTIFICATE DN=CN=hostname,OU=app,O=ibm,C=us, Serial=xxxxxxxxxxx
[04/Mar/2020:18:23:48.31655] 00002f26 3cff9700 - ERROR: Ensure correct certificate is marked as default certificate in plugin-key.kdb. Consult documentation regarding Administering application security and Securing communications for more information.
[04/Mar/2020:18:23:48.31657] 00002f26 3cff9700 - ERROR: Last validation error [575010]: GSKVAL_ERROR_NO_CHAIN_BUILT
[04/Mar/2020:18:23:48.31658] 00002f26 3cff9700 - ERROR: Subject [[Class=]GSKVALMethod::PKIX[Issuer=]OU=memberRoot,O=xxxx-xxx-xxx-xxx-xxxxxxxx,DC=com.ibm.ws.collective[#=]082d6a83e5ec[Subject=]CN=hostname,OU=app,O=ibm,C=us] failed certificate validation
[04/Mar/2020:18:23:48.31659] 00002f26 3cff9700 - ERROR: X509 Certificate validation log: [[Class=]GSKVALMethod::PKIX[Time=]2020:3:4:18:23:48.316[buildChain=][Error=]GSKVAL_ERR_NO_CHAIN_BUILT[Info=]OU=memberRoot,O=xxx-xxx-xxx-xxx-xxx,DC=com.ibm.ws.collective[Cert=][Issuer=]OU=memberRoot,O=xxx-xxx-xxx-xxx-xxxx,DC=com.ibm.ws.collective[#=]082d6a83e5ec[Subject=]CN=hostname,OU=app,O=ibm,C=us[=Cert][=buildChain]^M
]
[04/Mar/2020:18:23:48.31664] 00002f26 3cff9700 - ERROR: ws_common: websphereGetStream: Could not open stream
[04/Mar/2020:18:23:48.31667] 00002f26 3cff9700 - ERROR: ws_common: websphereExecute: Failed to create the stream
[04/Mar/2020:18:23:48.31668] 00002f26 3cff9700 - ERROR: ws_common: websphereHandleRequest: Failed to execute the transaction to 'default_node_app' on host 'hostname:10447'; will try another one
[04/Mar/2020:18:23:48.31669] 00002f26 3cff9700 - ERROR: ws_common: websphereWriteRequestReadResponse: Failed to find an app server to handle this request
[04/Mar/2020:18:23:48.31670] 00002f26 3cff9700 - ERROR: ESI: getResponse: failed to get response: rc = 2
[04/Mar/2020:18:23:48.31671] 00002f26 3cff9700 - ERROR: [xxx.xx.xx.17://app/ui/] ws_common: websphereHandleRequest: Failed to handle request rc=2
Thank you!
You said "imported" I assume this means an "add" operation in ikeyman/gskcmd/gskcapicmd? The two verbs in these tools have a different meaning.
I suspect you added the issued certificate (CN=hostname...) instead of the CA that issued the certificate (memberroot). The debug information in the WAS Plugin message implies that it couldn't chase the certificate up to a trusted root (as opposed to finding some X509 error w/ the root it had access to).
But, it could also be that you imported the "wrong" certificate with cn=memberroot. WebSphere does not always add the necessary Subject Key Identifier/Authority Key Identifier to be sure, so check carefully.
Ok, I got this working finally. It seems having a collective setup which used DefaultKeyStore id was somehow causing conflict with my Liberty plugin keystore.
I ended up re-creating everything (plugin-key.kdb keystore and the liberty plugin keystore which I named LibertyKeystore.jks). I dumped the collective stuff (not needed at this time anyways) and made an include as above called plugin-join-include.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<server description="IHS plugin join include file">
<featureManager>
<feature>ssl-1.0</feature>
</featureManager>
<keyStore id="defaultKeyStore" password="password"
location="${server.config.dir}/resources/security/LibertyKeystore.jks" />
<pluginConfiguration webserverPort="80" webserverSecurePort="8443"
pluginInstallRoot="/opt/IBM/wasadmin/Plugins"
sslKeyRingLocation="/opt/IBM/wasadmin/Plugins/config/webserver1/plugin-key.kdb"
sslStashFileLocation="/opt/IBM/wasadmin/Plugins/config/webserver1/plugin-key.sth"
sslCertlabel="LibertyKeystore"/>
</server>
I exchanged keys between the liberty server LibertyKeystore.jks and the IHS plugin-key.kdb keystores and pushed the newly generated plugin to the IHS server and bounced everything and it all seems to function without issue.
I do now notice in the /opt/IBM/wasadmin/HTTPServer/logs the error log streams:
[Wed Mar 04 21:32:28 2020] [error] [client xxx.xx.xx.17:65261] [7ff5a0000910] [19831] SSL0279E: SSL Handshake Failed due to fatal alert from client. Client sent fatal alert [level 2 (fatal), description 46 (certificate_unknown)] [xxx.xx.xx.17:65261 -> xxx.xx.xx.87:8443] [21:32:28.000934048] 0ms
The access logs show 200's. Maybe a non plugin "issue" at this point.

SSL Handshake Debugging not working any more with Apache Tomcat/9.0.0.M22

I have to debug a SSL Handshake on Tomcat (OS: MS Windows), so I followed the instructions found in the web an enabled it with the following line in setenv.bat:
set "JAVA_OPTS=%JAVA_OPTS% -Djavax.net.debug=ssl"
With Apache Tomcat/9.0.0.M21 everything works fine, when I opened the page with my browser I can see the handshake on the commandline.
With Apache Tomcat/9.0.0.M22 I only can see which certificates are beeing loaded on startup but after then when I call the server via browser no more output is generated on the commandline.
The only difference I could find out is that the Protocolhandler is different between those versions:
Apache Tomcat/9.0.0.M21 uses ProtocolHandler ["https-jsse-nio-8083"]
Apache Tomcat/9.0.0.M22 uses ProtocolHandler ["https-openssl-nio-8083"]
Is there anything I have to do additional to enable ssl handshake-debugging?
This is my Connector configured in server.xml:
<Connector port="8083" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="<Path to Keystore>"
keystorePass="<KeystorePW>" />
Try forcing JSSE use by adding sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation" in your Connector . For any reason it's detecting APR and trying to use OpenSSL which is not working. You might fill a bug or ask the Tomcat users mailing-list, but 9.0.0 was a development release.

Is it Possible to Configure Tomcat 7 SSL to access certificates via SunMSCAPI?

Is it Possible to Configure Tomcat 7 SSL to access certificates via SunMSCAPI?
We are currently deploying Tomcat 7 to an Azure PAAS Cloud Service, which creates all instances as Window Servers.
We have configured SSL in Tomcat such that it accesses the certificate from a keystore file using JSSE (not APR):
<Connector port="443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150"
scheme="https"
secure="true"
keystoreFile="xxxxx" keystorePass="xxxxx" keystoreType="PKCS12"
clientAuth="false"
SSLEnabled="true"
sslProtocol="TLS" />
We would like to configure Tomcat to access the Windows Server Cert Manager, because MS Azure tooling provides for easy ways to deploy certificates to the instances via Powershell/REST APIs. I know this can be done with jetty using the Java SunMSCAPI.
Can this also be done in Tomcat 7?
Any help would be appreciated.
Not yet tested: Tell Tomcat to use the SubMSCAPI keystoreprovider:
--JvmOptions="-Djavax.net.ssl.keyStoreProvider=SunMSCAPI -Djavax.net.ssl.trustStoreProvider=SunMSCAPI -Djavax.net.ssl.trustStoreType=Windows-Root"
Configure the connector as
<Connector ...
keyAlias="my.www.server" keyStoreFile="" keyStoreType="Windows-My"
The value of keyAlias is the common name of the certificate, see
keytool -list -providername SunMSCAPI -storetype Windows-My

Resources