You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WSO2 API Manager 4.2搭配AWS ALB的mTLS认证配置异常排查

问题:AWS ALB透传mTLS证书到WSO2 APIM 4.2解析失败

场景与配置

在前端部署AWS Application Load Balancer(ALB)的WSO2 API Manager 4.2平台中,为特定API配置Mutual TLS(mTLS)认证:

  • ALB采用透传模式配置mTLS
  • WSO2端将目标API设置为要求mTLS,并更新deployment.toml配置:
    [apimgt.mutual_ssl]
    certificate_header = "X-Amzn-Mtls-Clientcert"
    enable_client_validation = false
    client_certificate_encode = true
    

问题现象

调用API时WSO2返回认证失败错误:

curl -v https://WSO2-GW-ALB.env.dev/my-api/1.0.0/test --key client-v3.key --cert client-v3.crt

< content-type: application/json; charset=UTF-8
< set-cookie: AWSALBTG=xxxxxxxxxx...; Expires=Tue, 06 Aug  GMT; Path=/
< set-cookie: AWSALBTGCORS=xxxxxxxxxx...; Expires=Tue, 06 Aug 2024 14:03:35 GMT; Path=/; SameSite=None; Secure
< activityid: e18b453b-f9ff-4dec-8aaa-0e9ea316312e
< access-control-expose-headers:
< access-control-allow-origin: *
< access-control-allow-methods: GET
< x-forwarded-proto: https
< x-forwarded-for: 10.XX.XX.XX
< x-forwarded-port: 443
< access-control-allow-headers: authorization,Access-Control-Allow-Origin,Content-Type,SOAPAction,apikey,Internal-Key,Authorization
< x-amzn-trace-id: Root=1-6ccccf2b7-4c1026ccccc83630554457e0
< x-amzn-mtls-clientcert: -----BEGIN%20CERTIFICATE-----%0AMIIFJDCCAwxxxxxxxxxxxxxxxxxxxxxxxxygAwxAgI0Aw6<reduced>%0A-----END%20CERTIFICATE-----%0A
<
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection #0 to host WSO2-GW-ALB.env.dev left intact
{"code":"900900","message":"Unclassified Authentication Failure","description":"Error while validating into Certificate Existence"}

WSO2日志显示证书解析失败:

TID: [] [] [2024-07-30 13:32:12,953] ERROR {org.wso2.carbon.apimgt.gateway.handlers.Utils} - 
Error while validating into Certificate Existence org.wso2.carbon.apimgt.api.APIManagementException:
Error while converting into X509Certificate
        at org.wso2.carbon.apimgt.gateway.handlers.Utils.getClientCertificateFromHeader_aroundBody34(Utils.java:491)
        at org.wso2.carbon.apimgt.gateway.handlers.Utils.getClientCertificateFromHeader(Utils.java:1)
        at org.wso2.carbon.apimgt.gateway.handlers.Utils.getClientCertificate_aroundBody32(Utils.java:448)
        at org.wso2.carbon.apimgt.gateway.handlers.Utils.getClientCertificate(Utils.java:1)
        at org.wso2.carbon.apimgt.gateway.handlers.security.authenticator.MutualSSLAuthenticator.authenticate_aroundBody4(MutualSSLAuthenticator.java:105)
        at org.wso2.carbon.apimgt.gateway.handlers.security.authenticator.MutualSSLAuthenticator.authenticate(MutualSSLAuthenticator.java:1)
        at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.isAuthenticate_aroundBody56(APIAuthenticationHandler.java:546)
...
Caused by: java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: Incomplete BER/DER data
        at java.base/sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:115)
        at java.base/java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:355)
        at org.wso2.carbon.apimgt.gateway.handlers.Utils.getClientCertificateFromHeader_aroundBody34(Utils.java:488)

关键排查结论:ALB发送的X-Amzn-Mtls-Clientcert头仅对空格、换行做了URL编码,但未处理+、/、=这些字符,而WSO2期望接收完全URL编码的证书头,导致解码后证书格式损坏无法解析。

解决方案

1. 使用Lambda@Edge补全证书头编码

创建Lambda函数在ALB的请求阶段拦截并处理证书头,对未编码的字符进行补全编码:

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;
    
    if (headers['x-amzn-mtls-clientcert']) {
        let certHeader = headers['x-amzn-mtls-clientcert'][0].value;
        // 对+、/、=进行URL编码
        certHeader = certHeader.replace(/\+/g, '%2B')
                               .replace(/\//g, '%2F')
                               .replace(/=/g, '%3D');
        headers['x-amzn-mtls-clientcert'][0].value = certHeader;
    }
    
    callback(null, request);
};

将该Lambda关联到ALB的对应监听器,确保请求到达WSO2网关前完成编码处理。

2. 修改WSO2证书解析逻辑(自定义扩展)

修改WSO2网关的证书解析代码,在解码前先补全未编码的字符:
找到org.wso2.carbon.apimgt.gateway.handlers.Utils类的getClientCertificateFromHeader方法,添加以下代码:

// 在URL解码前补全字符编码
certHeader = certHeader.replace("+", "%2B")
                       .replace("/", "%2F")
                       .replace("=", "%3D");
// 执行原有解码逻辑
String decodedCert = URLDecoder.decode(certHeader, StandardCharsets.UTF_8.name());

重新打包APIM网关组件,替换原有jar包后重启网关。

3. 引入NGINX中间层转码

在ALB与WSO2网关之间部署NGINX,配置NGINX处理证书头编码后转发:

location / {
    proxy_pass http://wso2-gateway-group;
    # 处理证书头的未编码字符
    set $encoded_cert $http_x_amzn_mtls_clientcert;
    set $encoded_cert "${encoded_cert//+/%2B}";
    set $encoded_cert "${encoded_cert//\//%2F}";
    set $encoded_cert "${encoded_cert//=/%3D}";
    proxy_set_header X-Amzn-Mtls-Clientcert $encoded_cert;
    # 转发其他必要头信息
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

这种方式无需修改WSO2代码,适合快速落地。


内容的提问来源于stack exchange,提问作者Soufiane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:14:54