MuleSoft HTTP请求报403 Forbidden,PHP Curl却正常运行求助
排查MuleSoft HTTP请求403 Forbidden问题(对比PHP Curl正常代码)
正常运行的PHP Curl代码
$url="XXXXXX"; $key="XXXXXX"; $data='[{"producerNumber":"0500555"}]'; $relativeUrl = '/producer/npn'; $date = gmdate('Y-m-d\TH:i:s\Z'); $dataToSign = $relativeUrl.$data.$date.$key; $encoded= base64_encode( hash_hmac('sha256', $dataToSign, base64_decode($key), true) ); $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => $data, CURLOPT_HTTPHEADER => array( "Content-Type: application/json", "Accept: application/json", "Accept: */*", "REQUEST_CLIENT_ID: XXXX", "REQUEST_DATE: " . $date, "REQUEST_SIGNATURE: " . $encoded, ), )); $response = curl_exec($curl);
报错的MuleSoft HTTP请求配置
<http:request method="POST" doc:name="Request" doc:id="82492d2a-cd5e-417d-8078-43daaa982c45" config-ref="HTTP_Request_configuration" path="/npn"> <http:body ><![CDATA[[{"producerNumber":"0500555"}]]]></http:body> <http:headers><![CDATA[#[%dw 2.0 import dw::Crypto import * from dw::core::Binaries output application/json --- { "Content-Type": "application/json", "Accept": "application/json", "Accept": "*/*", "REQUEST_CLIENT_ID": "XXXXX", "REQUEST_DATE": vars.datevalue, "REQUEST_SIGNATURE": toBase64(Crypto::HMACWith(fromBase64(vars.key as Binary), vars.relativeUrl ++ vars.producerNo ++ vars.datevalue ++ vars.key as Binary,"HmacSHA256" )) }]]]></http:headers> </http:request>
错误日志
ERROR 2025-02-20 17:00:38,760 [[MuleRuntime].uber.05: [car-api].uber@org.mule.runtime.core.privileged.processor.chain.AbstractMessageProcessorChain.initialise:648 @778984a7] [processor: post:\postNpn:application\json:car-api-config/processors/5; event: 7fb0dc10-efde-11ef-852b-8a2347d95a3e] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler: Message : HTTP POST on resource 'His is my URL so hiding it' failed: forbidden (403). Element : post:\postNpn:application\json:car-event-api-config/processors/5 @ car-events-api:car-events-api.xml:221 (Request) Element DSL : <http:request method="POST" doc:name="Request" doc:id="82492d2a-cd5e-417d-8078-43daaa982c45" config-ref="HTTP_Request_configuration" path="/npn"> <http:body><![CDATA[ [{"producerNumber":"123456"}] ]]></http:body> <http:headers><![CDATA[ #[%dw 2.0 import dw::Crypto import * from dw::core::Binaries output application/json --- { "Content-Type": "application/json", "Accept": "application/json", "Accept": "*/*", "REQUEST_CLIENT_ID": "moo-com", "REQUEST_DATE": vars.datevalue, "REQUEST_SIGNATURE": toBase64(Crypto::HMACWith(fromBase64(vars.key as Binary), vars.relativeUrl ++ vars.producerNo ++ vars.datevalue ++ vars.key as Binary,"HmacSHA256" )) }] ]]></http:headers> </http:request> Error type : HTTP:FORBIDDEN FlowStack : at post:\postNpn:application\json:car-api-config(post:\postNpn:application\json:car-event-api-config/processors/5 @ car-events-api:car-events-api.xml:221 (Request)) at car-events-api-main(car-events-api-main/processors/0 @ car-events-api:car-events-api.xml:35) (set debug level logging or '-Dmule.verbose.exceptions=true' for everything) ******************************************************************************** ERROR 2025-02-20 17:00:38,768 [[MuleRuntime].uber.05: [car-api].uber@org.mule.runtime.core.privileged.processor.chain.AbstractMessageProcessorChain.initialise:648 @778984a7] [processor: post:\postNpn:application\json:car-api-config/processors/5; event: 7fb0dc10-efde-11ef-852b-8a2347d95a3e] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler: > ******************************************************************************** > Message : HTTP POST on resource 'This is my URL so hiding it' failed: forbidden (403). Element : (None) Element DSL : (None) Error type : HTTP:FORBIDDEN FlowStack : (None) (set debug level logging or '-Dmule.verbose.exceptions=true' for everything) ********************************************************************************
问题排查与修复方案
对比PHP和Mule的签名生成逻辑,核心差异导致403的原因如下:
1. 签名拼接内容不匹配
PHP中签名的原始字符串是:
$dataToSign = $relativeUrl.$data.$date.$key;
即相对路径 + 完整请求体 + UTC日期 + 密钥字符串。
而Mule中错误地用vars.producerNo(单个生产者编号)替换了完整请求体,并且把密钥转成Binary后拼接,和PHP的字符串拼接逻辑不一致。
2. 日期格式需严格对齐
PHP生成的日期是UTC时区的ISO8601格式:gmdate('Y-m-d\TH:i:s\Z'),Mule的vars.datevalue必须完全匹配该格式(包括T分隔符和末尾的Z),不能有任何时区或格式差异。
3. 相对路径需一致
PHP中$relativeUrl = '/producer/npn',但Mule请求的path是/npn,需确保vars.relativeUrl的值和PHP一致。
修正后的Mule配置(核心部分)
<http:request method="POST" doc:name="Request" doc:id="82492d2a-cd5e-417d-8078-43daaa982c45" config-ref="HTTP_Request_configuration" path="/npn"> <http:body ><![CDATA[[{"producerNumber":"0500555"}]]]></http:body> <http:headers><![CDATA[#[%dw 2.0 import dw::Crypto import * from dw::core::Binaries output application/json --- { "Content-Type": "application/json", "Accept": "application/json", "Accept": "*/*", "REQUEST_CLIENT_ID": "XXXXX", "REQUEST_DATE": now() >> "UTC" as String {format: "yyyy-MM-dd'T'HH:mm:ss'Z'"}, "REQUEST_SIGNATURE": toBase64( Crypto::HMACWith( fromBase64(vars.key), vars.relativeUrl ++ write(payload, "application/json") ++ (now() >> "UTC" as String {format: "yyyy-MM-dd'T'HH:mm:ss'Z'"}) ++ vars.key, "HmacSHA256" ) ) }]]]></http:headers> </http:request>
额外验证步骤
- 确保
vars.relativeUrl的值为/producer/npn,和PHP一致。 - 检查请求体的字符串格式:PHP中
$data是紧凑的[{"producerNumber":"0500555"}],Mule的write(payload, "application/json")需生成完全相同的字符串(无多余换行、空格)。 - 可以临时将PHP和Mule生成的
dataToSign、encoded值输出日志,对比是否完全一致,快速定位差异点。
内容的提问来源于stack exchange,提问作者Veera Raghava Prasad Govindara
相关产品推荐
相关产品推荐

