Amazon web services AWS S3:如何使用ColdFusion为Put对象副本生成签名?

Amazon web services AWS S3:如何使用ColdFusion为Put对象副本生成签名?,amazon-web-services,amazon-s3,coldfusion,Amazon Web Services,Amazon S3,Coldfusion,我试图在ColdFusion中用用户定义的元数据使用s3的put对象复制功能(s3替换文件)。我正在使用Joe Danziger的函数()创建签名。 然而,我不断得到我的签名不匹配的错误。有什么想法吗这是我的代码: public function setMetaDataForObject(string bucket, string objectKey, struct metadata){ var dateTimeString = GetHTTPTimeString(now());

我试图在ColdFusion中用用户定义的元数据使用s3的put对象复制功能(s3替换文件)。我正在使用Joe Danziger的函数()创建签名。 然而,我不断得到我的签名不匹配的错误。有什么想法吗这是我的代码:

public function setMetaDataForObject(string bucket, string objectKey, struct metadata){
    var dateTimeString = GetHTTPTimeString(now());
    writedump(metadata);
    var cs = "PUT\n\nimg/png\n#dateTimeString#\nx-amz-copy-source:/#arguments.bucket#/#arguments.objectKey#\nx-amz-metadata-directive:REPLACE\n";
    for(key in arguments.metadata){
            cs &= "#key#:#metadata[key]#\n";                
        }           
    cs &= "/#arguments.bucket#/#arguments.objectKey#";
    writeoutput(cs);
    var signature = createSignature(cs);
    var httpReq = new http();
        httpReq.setMethod("PUT");
        httpReq.setUrl("http://#arguments.bucket#.s3.amazonaws.com/#arguments.objectKey#" );
        //httpReq.setTimeout(timeout="300");
        httpReq.addParam(type="header", name="Date", value="#dateTimeString#");
        httpReq.addParam(type="header", name="Content-Type", value="img/png");
        httpReq.addParam(type="header", name="x-amz-copy-source", value="/#arguments.bucket#/#arguments.objectKey#");
        httpReq.addParam(type="header", name="x-amz-metadata-directive", value="REPLACE");
        httpReq.addParam(type="header", name="Authorization", value="AWS #variables.accessKeyId#:#signature#");
        for(var i in arguments.metadata){
            httpReq.addParam(type="header", name="#i#", value="#arguments.metadata[i]#");
        }

        //httpReq.addParam(type="body", value="#fileS3#");
        var result = httpReq.send().getPrefix(); writedump(result); 
}
private binary function HMAC_SHA1(required string signKey, required string signMessage){
    var jMsg = JavaCast("string",arguments.signMessage).getBytes("iso-8859-1");
    var jKey = JavaCast("string",arguments.signKey).getBytes("iso-8859-1");
    var key = createObject("java","javax.crypto.spec.SecretKeySpec");
    var mac = createObject("java","javax.crypto.Mac");

    key = key.init(jKey,"HmacSHA1");
    mac = mac.getInstance(key.getAlgorithm());
    mac.init(key);
    mac.update(jMsg);

    return mac.doFinal();
}

private string function createSignature(required string stringIn){
    var fixedData = replace(arguments.stringIn,"\n","#chr(10)#","all");
    var digest = HMAC_SHA1(variables.awsSecretKey, fixedData);
    var signature = ToBase64("#digest#");
    return signature;       
}
Joe Danziger的代码(我用脚本重写):

public function setMetaDataForObject(string bucket, string objectKey, struct metadata){
    var dateTimeString = GetHTTPTimeString(now());
    writedump(metadata);
    var cs = "PUT\n\nimg/png\n#dateTimeString#\nx-amz-copy-source:/#arguments.bucket#/#arguments.objectKey#\nx-amz-metadata-directive:REPLACE\n";
    for(key in arguments.metadata){
            cs &= "#key#:#metadata[key]#\n";                
        }           
    cs &= "/#arguments.bucket#/#arguments.objectKey#";
    writeoutput(cs);
    var signature = createSignature(cs);
    var httpReq = new http();
        httpReq.setMethod("PUT");
        httpReq.setUrl("http://#arguments.bucket#.s3.amazonaws.com/#arguments.objectKey#" );
        //httpReq.setTimeout(timeout="300");
        httpReq.addParam(type="header", name="Date", value="#dateTimeString#");
        httpReq.addParam(type="header", name="Content-Type", value="img/png");
        httpReq.addParam(type="header", name="x-amz-copy-source", value="/#arguments.bucket#/#arguments.objectKey#");
        httpReq.addParam(type="header", name="x-amz-metadata-directive", value="REPLACE");
        httpReq.addParam(type="header", name="Authorization", value="AWS #variables.accessKeyId#:#signature#");
        for(var i in arguments.metadata){
            httpReq.addParam(type="header", name="#i#", value="#arguments.metadata[i]#");
        }

        //httpReq.addParam(type="body", value="#fileS3#");
        var result = httpReq.send().getPrefix(); writedump(result); 
}
private binary function HMAC_SHA1(required string signKey, required string signMessage){
    var jMsg = JavaCast("string",arguments.signMessage).getBytes("iso-8859-1");
    var jKey = JavaCast("string",arguments.signKey).getBytes("iso-8859-1");
    var key = createObject("java","javax.crypto.spec.SecretKeySpec");
    var mac = createObject("java","javax.crypto.Mac");

    key = key.init(jKey,"HmacSHA1");
    mac = mac.getInstance(key.getAlgorithm());
    mac.init(key);
    mac.update(jMsg);

    return mac.doFinal();
}

private string function createSignature(required string stringIn){
    var fixedData = replace(arguments.stringIn,"\n","#chr(10)#","all");
    var digest = HMAC_SHA1(variables.awsSecretKey, fixedData);
    var signature = ToBase64("#digest#");
    return signature;       
}
我解决了这个问题: 标题需要按字母顺序排序! (传入createSignature函数时..它似乎没有给出实际http头的问题) 以下是我的更新代码:

public function setMetaDataForObject(required string bucket, required string objectKey, struct metadata, string contentType){

    if(!isdefined("argumetns.contentType")){
        var meta = getMetaDataForObject(arguments.bucket, arguments.objectKey);
        arguments.contentType = meta['Content-type'];
    }

    var dateTimeString = GetHTTPTimeString(now());
    var cs = "PUT\n\n#arguments.contentType#\n#dateTimeString#\nx-amz-copy-source:/#arguments.bucket#/#arguments.objectKey#\n";
    if(isdefined("arguments.metadata")){
        for(key in structSort(arguments.metadata)){
                cs &= "#key#:#metadata[key]#\n";                
            }
    }           
    cs &= "x-amz-metadata-directive:REPLACE\n/#arguments.bucket#/#arguments.objectKey#";
    var signature = createSignature(cs);
    var httpReq = new http();
        httpReq.setMethod("PUT");
        httpReq.setUrl("http://#arguments.bucket#.s3.amazonaws.com/#arguments.objectKey#" );
        httpReq.addParam(type="header", name="Date", value="#dateTimeString#");
        httpReq.addParam(type="header", name="Content-Type", value="img/png");
        httpReq.addParam(type="header", name="x-amz-copy-source", value="/#arguments.bucket#/#arguments.objectKey#");
        httpReq.addParam(type="header", name="x-amz-metadata-directive", value="REPLACE");
        httpReq.addParam(type="header", name="Authorization", value="AWS #variables.accessKeyId#:#signature#");
        if(isdefined("arguments.metadata")){
            for(var i in arguments.metadata){
                httpReq.addParam(type="header", name="#i#", value="#arguments.metadata[i]#");
            }
        }
        var result = httpReq.send().getPrefix(); writedump(result); 
}