将启用SSL的SpringBoot WAR包部署至外部Tomcat服务器遇问题
Hey there, let's work through this SSL problem you're facing—deploying your Spring Boot app (which works locally with SSL) as a WAR to an external SSL-enabled Tomcat but getting errors on requests. I've dealt with similar headaches before, so here's a step-by-step breakdown of what to check and fix:
1. Remove Spring Boot's Embedded SSL Configuration
First off, your external Tomcat is already handling SSL termination, so your Spring Boot app doesn't need to manage its own SSL settings anymore. Having both configured will cause conflicts.
Go into your application.properties (or application.yml) and comment out/delete all SSL-related properties:
# server.ssl.key-store=classpath:your-keystore.jks # server.ssl.key-store-password=your-password # server.ssl.key-store-type=JKS # server.ssl.key-alias=your-alias
This tells Spring Boot to run as a regular web app, relying on Tomcat to handle the HTTPS layer.
2. Verify WAR Deployment Setup
Make sure your Spring Boot app is properly configured for WAR deployment. You need a SpringBootServletInitializer subclass in your project to let Tomcat bootstrap your app correctly:
public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(YourSpringBootApplication.class); } }
If this class is missing, Tomcat won't be able to start your Spring Boot app properly, leading to unexpected errors.
3. Configure External Tomcat to Pass SSL Context to Spring Boot
When Tomcat handles HTTPS, it forwards the request to your Spring Boot app over HTTP. But your app needs to know the original request was HTTPS (for things like URL generation, security rules, etc.). Update Tomcat's server.xml Connector configuration to add these parameters:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="/path/to/your/tomcat-keystore.jks" type="RSA" /> </SSLHostConfig> <!-- These parameters inform Spring Boot about the original HTTPS request --> <Parameter name="scheme" value="https" /> <Parameter name="secure" value="true" /> <Parameter name="proxyPort" value="443" /> </Connector>
Then, add these properties to your Spring Boot application.properties to let it trust these forwarded headers:
server.use-forward-headers=true server.tomcat.protocol-header=x-forwarded-proto
4. Confirm Access Path & Port Mapping
Double-check your request URL structure:
- When deployed as a WAR, your app will have a context path matching your WAR filename (e.g., if your WAR is
myapp.war, the path ishttps://your-domain/myapp/showPage). If you want it to be the root path, rename the WAR toROOT.waror configure Tomcat'scontext.xmlaccordingly. - Ensure Tomcat's HTTPS port (usually 443) is open and accessible—don't try to hit the Spring Boot embedded port (like 8443) on the external server.
5. Dig Into Logs for Specific Errors
Since you mentioned there's an error screenshot you can't share, the next best step is to check logs:
- Tomcat logs: Look in
tomcat-home/logs/catalina.outorlocalhost.logfor SSL handshake errors, deployment failures, or request forwarding issues. - Spring Boot logs: If you've configured logging for your app, check for exceptions related to request processing, security, or header validation.
Common issues here might include missing SSL certificates in Tomcat's keystore, permission issues on the keystore file, or Spring Security rejecting requests because it doesn't recognize the HTTPS context.
6. Adjust Spring Security Configuration (If Used)
If your app uses Spring Security, it might be blocking requests because it thinks they're HTTP instead of HTTPS. Update your security config to trust the forwarded protocol header:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http // Trust the X-Forwarded-Proto header from Tomcat .requiresChannel() .requestMatchers(r -> r.getHeader("X-Forwarded-Proto") != null) .requiresSecure() .and() // Rest of your security rules... .authorizeRequests() .antMatchers("/showPage").permitAll() .anyRequest().authenticated(); } }
This ensures Spring Security recognizes the original request was HTTPS even though it's received as HTTP from Tomcat.
内容的提问来源于stack exchange,提问作者Rahul Devan

