JDK 17环境下Payara 5无法读取客户端证书问题排查
JDK 17 + Payara 5 无法读取客户端证书的排查与解决
问题描述
在简单WebFilter中读取客户端证书,JDK 11环境下运行正常,但升级服务器到JDK 17后,无法从请求中读取到客户端证书。尝试以下两种getAttribute调用,均返回null:
// JDK 17环境尝试的语句 X509Certificate[] certificates = (X509Certificate[]) request.getAttribute("jakarta.servlet.request.X509Certificate");
// JDK 11环境可用的语句 X509Certificate[] certificates = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
测试用Curl请求命令:
curl --cacert server-cert.pem --cert client-cert.pem --key client-key.pem https://localhost:8181/st/echo --insecure
服务器环境
- Payara 5.2022.4
- JDK 11(运行正常)
- JDK 17(读取证书失败)
SSL握手调试日志片段
[2023-10-31T07:20:51.257+0100] [Payara 5.2022.4] [SEVERE] [] [] [tid: _ThreadID=94 _ThreadName=http-thread-pool::http-listener-2(1)] [timeMillis: 1698733251257] [levelValue: 1000] [[ javax.net.ssl|DEBUG|E5|http-thread-pool::http-listener-2(1)|2023-10-31 07:20:51.255 CET|CertificateRequest.java:635|Produced CertificateRequest handshake message ( "CertificateRequest": { "certificate types": [ecdsa_sign, rsa_sign, dss_sign] "supported signature algorithms": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, ed25519, ed448, rsa_pss_rsae_sha256, ] } ) javax.net.ssl|DEBUG|E5|http-thread-pool::http-listener-2(1)|2023-10-31 07:20:51.256 CET|ServerHelloDone.java:97|Produced ServerHelloDone handshake message ( <empty> ) ]] ......... [2023-10-31T07:20:51.268+0100] [Payara 5.2022.4] [SEVERE] [] [] [tid: _ThreadID=96 _ThreadName=http-thread-pool::http-listener-2(3)] [timeMillis: 1698733251268] [levelValue: 1000] [[ javax.net.ssl|DEBUG|06|http-thread-pool::http-listener-2(3)|2023-10-31 07:20:51.268 CET|Finished.java:459|Produced server Finished handshake message ( "Finished": { "verify data": { 0000: F9 74 05 86 F7 A5 08 9E 75 49 F0 09 }'} ) ]] [2023-10-31T07:20:51.274+0100] [Payara 5.2022.4] [INFO] [] [] [tid: _ThreadID=98 _ThreadName=http-thread-pool::http-listener-2(5)] [timeMillis: 1698733251274] [levelValue: 800] [[ No client certificate found in the request.]] [2023-10-31T07:20:51.277+0100] [Payara 5.2022.4] [SEVERE] [] [] [tid: _ThreadID=94 _ThreadName=http-thread-pool::http-listener-2(1)] [timeMillis: 1698733251277] [levelValue: 1000] [[ javax.net.ssl|DEBUG|E5|http-thread-pool::http-listener-2(1)|2023-10-31 07:20:51.277 CET|Alert.java:238|Received alert message ( "Alert": { "level" : "warning", "description": "close_notify" } )
排查与解决步骤
1. 确认Payara版本兼容性
Payara 5.2022.4对JDK 17的支持有限,部分SSL逻辑在JDK 17的安全约束下会异常。建议升级到Payara 5最新维护版本,或直接切换到Payara 6(完全兼容Jakarta EE 9+和JDK 17)。
2. 检查SSL监听器客户端认证配置
在Payara管理控制台操作:
- 进入
Configurations > server-config > HTTP Service > HTTP Listeners > http-listener-2(你的HTTPS监听器) - 确保
Client Authentication设置为Required或Optional(按需选择) - 验证
SSL3/TLS配置中,信任库已正确导入客户端证书的CA根证书
3. 调整JDK 17安全参数
JDK 17默认收紧SSL策略,需在Payara启动参数中添加以下JVM参数:
-Djdk.tls.client.certificates=allow -Djavax.net.ssl.trustStore=/path/to/your/truststore.jks -Djavax.net.ssl.trustStorePassword=your-truststore-password
同时确认客户端与服务器使用兼容的TLS版本(如TLS 1.2+),避免禁用必要协议。
4. 验证客户端证书与信任库匹配
确保客户端证书的CA证书已导入服务器信任库,且客户端证书的签名算法在服务器日志显示的supported signature algorithms列表中(如ecdsa_secp256r1_sha256等)。
5. 替换证书获取方式
尝试通过SSL会话直接获取证书,替代getAttribute:
import javax.net.ssl.SSLSession; import javax.servlet.http.HttpServletRequest; import java.security.cert.X509Certificate; // 在WebFilter的doFilter方法中 HttpServletRequest httpRequest = (HttpServletRequest) request; SSLSession sslSession = (SSLSession) httpRequest.getAttribute("javax.servlet.request.ssl_session"); if (sslSession != null) { try { X509Certificate[] certs = (X509Certificate[]) sslSession.getPeerCertificates(); // 处理证书逻辑 } catch (Exception e) { e.printStackTrace(); } }
内容的提问来源于stack exchange,提问作者Wasif Kirmani
相关产品推荐
相关产品推荐

