Confluence Java后端REST API SSL配置问题:服务端下载附件用于OpenAI语音转文本时抛出SSL错误
我太懂你这种前后端不一致的头疼了——前端React 18明明能顺利把oga文件上传到Confluence页面当附件,可后端用Java REST Client下载这个文件准备传给OpenAI做语音转文本时,偏偏就抛出SSL错误,而且光给Apache 2配SSL根本不管用,必须得把Confluence所在的Tomcat配置好才行。
先给你梳理下核心问题和对应的解决步骤:
一、补全Tomcat的SSL Connector配置
你提到修改了Ubuntu 20.04上的./conf/server.xml,但给出的配置片段不完整。要让Tomcat支持HTTPS,必须在server.xml里配置完整的SSL Connector节点,示例如下:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" connectionTimeout="20000" redirectPort="8443"> <SSLHostConfig> <Certificate certificateKeystoreFile="/opt/atlassian/confluence/conf/your-keystore.jks" type="RSA" certificateKeystorePassword="你的密钥库密码" certificateKeyPassword="你的密钥密码"/> </SSLHostConfig> </Connector>
注意要点:
- 确保
certificateKeystoreFile路径指向你的JKS密钥库文件(如果是PEM证书,可能需要先转换成JKS格式) - 密码要和创建密钥库时设置的一致
- 开启
scheme="https"和secure="true",让Tomcat识别这是HTTPS连接器
二、修正Confluence的Base URL配置
登录Confluence后台,进入General Configuration,把Base URL改成HTTPS开头的完整地址(比如https://your-confluence-domain.com)。如果这里还是HTTP,Confluence的API返回的附件下载URL会是HTTP协议,后端Java请求时自然会触发SSL错误。
三、解决Java客户端的证书信任问题
如果Confluence用的是自签名证书或者内部CA颁发的证书,Java的JVM默认不会信任它,这时候有两种处理方式:
方式1:把证书导入JVM全局信任存储
- 先导出Confluence的证书:
openssl s_client -connect your-confluence-domain:8443 </dev/null | openssl x509 -outform PEM > confluence-cert.pem
- 导入到JVM的
cacerts信任库(替换成你的JDK实际路径):
keytool -import -alias confluence-cert -file confluence-cert.pem -keystore /usr/lib/jvm/java-11-openjdk-amd64/jre/lib/security/cacerts
默认cacerts的密码是changeit,按提示确认导入即可。
方式2:在Java代码中自定义SSL上下文(适合不修改全局配置的场景)
如果不想改动JVM全局信任库,可以在代码里单独配置信任Confluence的证书:
import java.io.FileInputStream; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.KeyStore; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClientBuilder; // 加载Confluence证书文件 CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream certIn = new FileInputStream("confluence-cert.pem"); X509Certificate cert = (X509Certificate) cf.generateCertificate(certIn); certIn.close(); // 创建自定义信任管理器 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("confluence-cert", cert); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); // 构建带自定义SSL上下文的HttpClient SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); HttpClient httpClient = HttpClientBuilder.create().setSSLContext(sslContext).build(); // 后续用这个httpClient来发送下载附件的REST请求
四、检查Apache反向代理的SSL传递配置
如果用Apache做反向代理到Tomcat,要确保代理时传递正确的HTTPS头,让Confluence知道请求是通过HTTPS过来的。在Apache的虚拟主机配置里添加:
ProxyPass / http://localhost:8090/ ProxyPassReverse / http://localhost:8090/ RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Port "443"
这样Confluence生成的附件URL才会是HTTPS协议,避免后端请求时出现协议不匹配的SSL错误。
五、验证附件下载URL的正确性
在Java代码里先打印出要请求的附件下载URL,确认它是HTTPS开头,域名、端口都和你的Confluence实例一致。如果URL是HTTP的,那就要回头检查Base URL和反向代理的配置了。
备注:内容来源于stack exchange,提问作者Matti Kiviharju




