Amazon AWS API中的签名错误无效" itemsearch"使用ColdFusion调用

时间:2017-05-11 17:22:05

标签: api amazon-web-services coldfusion aws-sdk

我遇到了一个无效签名的错误。我正在调用itemsearch API,但在此之前我的签名(版本4)无效。

这是cfc文件" amazonsig.cfc"我是从http://amazonsig.riaforge.org/index.cfm?event=action.download得到的:

<cfcomponent hint="Amazon Product Advertising API Signature Generator">

    <cffunction name="signRequest" returntype="string" output="false"
        hint="Sign a request">

        <cfargument name="request" required="yes" type="string">
        <cfargument name="secretKey" required="yes" type="string">

        <!--- "Local" variable scope --->
        <cfset var lc = structnew()>

        <!--- Extract the URL part of the request and strip the protocol --->
        <cfset lc.requesturl = listfirst(arguments.request, "?")>
        <cfset lc.requesturl = replacenocase(lc.requesturl, "http://", "")>

        <!--- Split into host and path --->
        <cfset lc.host = listfirst(lc.requesturl, "/")>
        <cfset lc.path = right(lc.requesturl, len(lc.requesturl) - len(lc.host))>

        <!--- Process the query string parameters into a structure --->
        <cfset lc.querystring = listlast(arguments.request, "?")>
        <cfset lc.strParams = structnew()>
        <cfloop list="#lc.querystring#" index="i" delimiters="&">
            <cfset lc.strParams[listfirst(i, "=")] = urldecode(listlast(i, "="))>
        </cfloop>

        <!--- Add the timestamp --->
        <cfif not StructKeyExists(lc.strParams, "Timestamp")>
            <cfset lc.utcdate = dateconvert("local2Utc", now())>
            <cfset lc.timestamp = dateformat(lc.utcdate, 'yyyy-mm-dd') & "T" & timeformat(lc.utcdate, 'HH:mm:ss') & "Z">
            <cfset lc.strParams["Timestamp"] = lc.timestamp>
        </cfif>

        <!--- Sort the parameters --->
        <cfset lc.keys = listsort(structkeylist(lc.strParams), "text")>

        <!--- Generate a new query string including timestamp, with parameters in the correct order, encoding as we go --->
        <cfset lc.qs = "">
        <cfloop list="#lc.keys#" index="i">
            <cfset lc.qs = lc.qs & rfc3986EncodedFormat(i) & "=" & rfc3986EncodedFormat(lc.strParams[i]) & "&">
        </cfloop>

        <!--- Strip off the last & --->
        <cfset lc.qs = left(lc.qs, len(lc.qs)-1)>

        <!--- Build the string to sign --->
        <cfset lc.stringToSign = "GET" & chr(10)>
        <cfset lc.stringToSign = lc.stringToSign & lc.host & chr(10)>
        <cfset lc.stringToSign = lc.stringToSign & lc.path & chr(10)>
        <cfset lc.stringToSign = lc.stringToSign & lc.qs>

        <!--- Create the signature --->
        <cfset lc.binaryMsg = JavaCast("string",lc.stringToSign).getBytes("iso-8859-1")>
        <cfset lc.binaryKey = JavaCast("string",arguments.secretKey).getBytes("iso-8859-1")>
        <cfset lc.key = createObject("java","javax.crypto.spec.SecretKeySpec")>
        <cfset lc.key.init(lc.binaryKey,"HmacSHA256")>
        <cfset lc.hmac = createObject("java","javax.crypto.Mac")>
        <cfset lc.hmac = lc.hmac.getInstance("HmacSHA256")>
        <cfset lc.hmac.init(lc.key)>
        <cfset lc.hmac.update(lc.binaryMsg)>
        <cfset lc.signature = lc.hmac.doFinal()>

        <!--- Return the new request URL --->
        <cfreturn "http://" & lc.host & lc.path & "?" & lc.qs & "&Signature=" & urlencodedformat(tobase64(lc.signature))>

    </cffunction>

    <cffunction name="rfc3986EncodedFormat" returntype="string" output="false"
        hint="Perform some character encoding">
        <cfargument name="text" required="yes" type="string">
        <!--- "Local" variable scope --->
        <cfset var lc = structnew()>
        <cfset lc.objNet = createObject("java","java.net.URLEncoder")>
        <cfset lc.encodedText = lc.objNet.encode(arguments.text, 'utf-8').replace("+", "%20").replace("*", "%2A").replace("%7E", "~")>
        <cfreturn lc.encodedText>
    </cffunction>
</cfcomponent>

这是我的cfm文件&#34; amazonsig.cfm&#34;

<cfset requrl = "http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&Operation=ItemSearch&AWSAccessKeyId=aaaa&AssociateTag=aaaaa&SearchIndex=Books&Keywords=Harry&ResponseGroup=Images,ItemAttributes,Offers">

<cfset amazonsig = createObject("component", "amazonsig")>
<cfset abc = amazonsig.signrequest(requrl,"aaa")>


<cfhttp url="#abc#" method="GET" result="response"  resolveurl="yes">
<cfhttpparam type="header" name="Content-Type" value="application/json" >
<cfhttpparam type="header" name="Accept" value="application/json" >

</cfhttp>
<cfdump var="#response#">

注意:签名网址是正确的,因为我直接在浏览器中点击并且响应正确返回,但在&lt; cfhttp&gt;中这是错误的。

Enter image description here

1 个答案:

答案 0 :(得分:0)

我已经解决了,我使用的是coldfusion 11和jdk 1.7,但是当我使用jdk 1.8在coldfusion 10上运行代码时,它已成功运行。