WSO2调用下载AWS S3图片时URL参数解码致签名不匹配问题
WSO2调用AWS S3预签名URL时签名不匹配问题
问题描述
通过WSO2流程下载AWS S3图片时,URL中的签名参数被自动解码。例如原签名参数为RmHyI5zRW5nxwWvitbWMsa%2FEwjA%3D,经Call Mediator发送请求后,签名变为RmHyI5zRW5nxwWvitbWMsa/EwjA=(%2F转为/、%2B转为+、%3D转为=),导致AWS服务器返回签名不匹配错误。
AWS错误响应
<?xml version='1.0' encoding='utf-8'?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <Error> <Code>SignatureDoesNotMatch</Code> <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message> <AWSAccessKeyId>ASIA4OAOFXPAHYQCKZGD</AWSAccessKeyId> <StringToSign>GET application/json x-amz-security-token:IQoJb3JpZ2luX2VjEGcaCXVzLXdlc3QtMiJGMEQCIErbF6+3Qj1e8UZuSI3RPK/Fu9M+m5vfTbPG7pV4uEm8AiAMcqQ+sxViOrKF5UiGYCxZvN7XIB8ZTTNh1/S2RAQRdyr2AghAEAMaDDg1NDcyODIyNzc3NiIMjDVIwtnu3pjT+tmzKtMCys9cFKUxOM+QdH9RruzAp/RHcIargE43nDG1/h4gHT7QU4iBgb29PKXMtSwsgzSAeakoKk6q+xmmgJrqnerrgK6zIRIhZiMvhDAHdfvHs1szEMcxRHwiMDCDuhxv/o481dhuJBWBuA68jbft3iq2Z+k8o1EuXpLBg72pE5hjX0lDVfnYWRvHQGGxV5c8qQHObgzHAIHQfYdr16Cj/lgrpq+at6QO0qxWcYESDlTTITAMekZVK9cyp6bQyEmTDD4epM6EymfBXa0fByazpcTXsMg2UXSCZxd54Zk9SUAf28gqJoemiOXX6HQr8BfnJk2NBcLmwGvDASB7kqdInJcUZBo/KMJ6C1qcGOp8BEkNCJ+0geKIVKib0Nxf73ooXljSKJkQK+OcEkfy9fL4ysXyiYrgrcti/AXHV2O22dWQG4DaYQS2awLcFA0RjWNMC5vvwpSHWzpeA6hziYKJgqhgSasKD6M+PwgGTA+N5ygXP6RyynrF2oZ64eiQlMemYxlABez8iFnIkK7RPUi+D0iDH+W6XJCWsGFzTEIR1vBEezNtQlR7W8t9mlnlx /smile-results-prod/production/000000/353/353-0000010928-hmwgs7m5xvquv196pv48uly3rpobfp/SID_Preview_Full.jpg</StringToSign> <SignatureProvided>RmHyI5zRW5nxwWvitbWMsa/EwjA=</SignatureProvided> <StringToSignBytes>47 45 54 0a 0a 61 70 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e 0a 31 36 39 33 38 31 35 30 38 32 0a 78 2d 61 6d 7a 2d 73 65 63 75 72 69 74 79 2d 74 6f 6b 65 6e 3a 49 51 6f 4a 62 33 4a 70 5a 32 6c 75 58 32 56 6a 45 47 63 61 43 58 56 7a 4c 58 64 6c 63 33 51 74 4d 69 4a 47 4d 45 51 43 49 45 72 62 46 36 2b 33 51 6a 31 65 3 8 6d 77 67 73 37 6d 35 78 76 71 75 76 31 39 36 70 76 34 38 75 6c 79 33 72 70 6f 62 66 70 2f 53 49 44 5f 50 72 65 76 69 65 77 5f 46 75 6c 6c 2e 6a 70 67</StringToSignBytes> <RequestId>SG78VW8C3M74MB6D</RequestId> <HostId>EhqRjZNgna9/eDzMryNIiYYbN5mw14oLgmXEhsx28yMvVrBShweObyHxku810k8ecobkai+Twjg=</HostId> </Error> </soapenv:Body> </soapenv:Envelope>
当前WSO2配置
<resource methods="POST" uri-template="/test"> <inSequence> <property expression="$body//image_url" name="uri.var.selfie_image" scope="default" type="STRING"/> <call> <endpoint> <http method="get" uri-template="{uri.var.selfie_image}"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <respond/> </inSequence> <outSequence/> <faultSequence/> </resource>
解决方案
原因分析
WSO2的HTTP Endpoint在使用uri-template时,会自动对变量内容进行URL解码操作。而AWS S3预签名URL的签名参数是经过特殊编码生成的,一旦被解码就会破坏签名的完整性,导致AWS验证失败。
方案1:使用Send Mediator替代Call Mediator
通过send mediator直接传递原始URL,避免uri-template的自动解码:
<resource methods="POST" uri-template="/test"> <inSequence> <property expression="$body//image_url" name="uri.var.selfie_image" scope="default" type="STRING"/> <!-- 设置为OUT_ONLY模式,无需等待响应 --> <property name="OUT_ONLY" value="true"/> <send> <endpoint> <http method="get" uri="{uri.var.selfie_image}"/> </endpoint> </send> <respond/> </inSequence> <outSequence/> <faultSequence/> </resource>
方案2:关闭URI模板的自动解码
如果必须使用call mediator,可在HTTP Endpoint中添加disableUrlEscaping="true"属性,禁用自动解码:
<resource methods="POST" uri-template="/test"> <inSequence> <property expression="$body//image_url" name="uri.var.selfie_image" scope="default" type="STRING"/> <call> <endpoint> <http method="get" uri-template="{uri.var.selfie_image}" disableUrlEscaping="true"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <respond/> </inSequence> <outSequence/> <faultSequence/> </resource>
注意事项
预签名URL的有效性完全依赖其原始编码状态,任何额外的编码/解码操作都会导致签名验证失败。必须确保WSO2传递给AWS的URL与生成的预签名URL完全一致,不得有任何修改。
内容的提问来源于stack exchange,提问作者Pritish Mohanty
相关产品推荐
相关产品推荐

