spring-projects / spring-projects/spring-boot

Support tomcat-coyote-ffm for native ssl with embedded Tomcat

Open
#50,100 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: on-hold type: enhancement
Dominant language
Java
Stars
81.5k
Forks
42.7k
Avg merge
2d 4h
Merged PRs (30d)
65

Description

Enhancement Request

I would like for Spring Boot to provide first-class support for autoconfiguring tomcat-coyote-ffm for native ssl without using APR or tomcat-native.

Background

Setting up APR and tomcat-native is somewhat complicated, and difficult to "get right".

Tomcat recently introduced a new tomcat-coyote-ffm module, which allows using native ssl without requiring APR or tomcat-native. Internally tomcat-coyote-ffm uses Java's Foreign Function & Memory API to directly call libssl.

Spring Boot currently has first-class autoconfiguration support for native ssl using APR and tomcat-native, but does not offer first-class support for tomcat-coyote-ffm.

Currently, it is possible to enable tomcat-coyote-ffm in a Spring Boot app with embedded Tomcat, but it is not intuitive or documented anywhere.

It would be great if Spring Boot provided first-class support for using tomcat-coyote-ffm.

The current situation

Enabling tomcat-coyote-ffm in a Spring Boot app with embedded Tomcat today is not intuitive.

The typical way to enable tomcat-coyote-ffm module is by registering a OpenSSLLifecycleListener lifecycle listener on Tomcat's Server object (as described in the tomcat docs).

Spring Boot does not provide direct access to embedded Tomcat's Server object, so subclassing TomcatServletWebServerFactory is required.

public class FfmOpenSslTomcatServletWebServerFactory extends TomcatServletWebServerFactory {

	@Override
	protected Tomcat createTomcat() {
		Tomcat tomcat = super.createTomcat();
		tomcat.getServer().addLifecycleListener(new OpenSSLLifecycleListener());
		return tomcat;
	}
}

Then, declare the FfmOpenSslTomcatServletWebServerFactory bean:

@Configuration(proxyBeanMethods = false)
public class TomcatFfmOpenSslConfig {

	@Bean
	public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
		return new FfmOpenSslTomcatServletWebServerFactory();
	}
}

And also add a dependency on tomcat-coyote-ffm, while excluding the non-embedded Tomcat transitive dependencies (side note: this Tomcat feature request should help this situation).

		<!--
			tomcat-coyote-ffm provides the FFM/panama-based OpenSSL integration
			(org.apache.tomcat.util.net.openssl.panama.*) used by
			org.apache.catalina.core.OpenSSLLifecycleListener (which lives in
			tomcat-embed-core). This replaces tomcat-native / APR for OpenSSL.
			Its transitive deps (tomcat-coyote / tomcat-juli / tomcat-util) are
			excluded because tomcat-embed-core already ships those classes under
			the same FQCNs; keeping both would put duplicate classes on the
			classpath.
		-->
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-coyote-ffm</artifactId>
			<version>${tomcat.version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.apache.tomcat</groupId>
					<artifactId>tomcat-coyote</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.apache.tomcat</groupId>
					<artifactId>tomcat-juli</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.apache.tomcat</groupId>
					<artifactId>tomcat-util</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
Desired solution

I'd like Spring Boot to be able to auto-configure tomcat-coyote-ffm if it is available on the classpath. Specifically, if org.apache.tomcat.util.net.openssl.panama.OpenSSLLibrary is on the classpath, then add a OpenSSLLifecycleListener to Tomcat's Server object.

Perhaps add a tomcat.server.use-ffm property, parallel to tomcat.server.use-apr.

Alternatively, if direct support for tomcat-coyote-ffm cannot be provided... at least provide the ability to register a lifecycle listener on Tomcat's Server object, so that subclassing TomcatServletWebServerFactory is not required. (Note that it is currently possible to access the Context object to add a lifecycle listener, but not the Server object).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read Spring Boot’s existing APR/native SSL auto-configuration and the TomcatServletWebServerFactory entry point, then compare how OpenSSLLifecycleListener can be attached to Tomcat’s Server. Check the OpenSSLLibrary classpath condition and the proposed tomcat.server.use-ffm behavior; done means embedded Tomcat can use tomcat-coyote-ffm without subclassing the factory or manually registering the listener.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.