大家好,我试图让SAS调用cURL,从AWS下载文件。
我目前正在获得#34; AWS身份验证需要有效的日期或x-amz-date标头"错误,但我已经检查了日期(星期五,2016年1月29日14:47:15 GMT + 1300),它似乎是正确的格式,所以我不确定发生了什么。当我昨天用我认为相同的代码进行测试时,我得到了一个错误,就像#34;问题签名签名"。
经过一天的努力,我希望别人可能做过类似的事情并且可以提供帮助。这是我目前正在使用的代码。我会提到我不是AWS的专家,所以我可能搞砸了一些基本的东西,但我还没有能够解决它。
* cludged from:
http://stackoverflow.com/questions/27658147/download-private-file-from-s3-using-bash
https://communities.sas.com/t5/Base-SAS-Programming/Using-sas-secure-to-generate-hmac-sha1-oauth-signature/td-p/169922 ;
%LET cUrl_exe = C:\Apps\cUrl\cUrl.exe ; * change if yours is in a different place ;
%LET s3Key=<access_key>;* change this line ;
%LET s3Secret=<secret_key>;* change this line ;
%LET out_file = <outfile_path>; * change this line ;
%LET file = test.txt ; * change this line ;
%LET bucket = <bucket name>; * change this line ;
%LET resource = "/&bucket./&file." ;
%PUT Resource = [&Resource.] ;
%LET contentType = 'text/html' ; * this may not matter? ;
*dateValue="`date +'%a, %d %b %Y %H:%M:%S %z'`" ;
PROC FORMAT ;
PICTURE HTTPTime
(DEFAULT = 29)
OTHER = '%a, %0d %b %Y %0H:%0M:%0S'
(DATATYPE = DATETIME) ;
RUN ;
DATA _NULL_ ;
CALL SYMPUT("dateValue", STRIP(PUT(DATETIME(), HTTPTime.)) || " GMT+1300") ; * SHOULD BE ABLE TO USE %Z TO GET UTC OFFSET NEED TO CHANGE TO +1200 WHEN NOT IN DST ;
RUN ;
%PUT dateValue = [&dateValue.] ;
DATA _NULL_ ;
stringToSign = '"GET' || '0A'X ||
'0A'X ||
/* STRIP(SYMGET("contentType")) || '0A'X ||*/
STRIP(SYMGET("dateValue")) || '0A'X ||
STRIP(SYMGET("resource")) || '"' ;
PUT stringToSign= ;
CALL SYMPUT("stringToSign", STRIP(TRANWRD(stringToSign, '"', '""'))) ;
RUN ;
proc groovy;
add sasjar="commons_codec" ; *version="1.7.0.0_SAS_20121211183158";*version may differ based on your installation. Check your SAS Versioned Jar Repository;
submit "&s3secret." "&stringToSign.";
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import org.apache.commons.codec.binary.Base64
def base64hmacsha256(key, message) {
mac = Mac.getInstance("HmacSHA256")
mac.init(new SecretKeySpec(key.getBytes(), "HmacSHA256"))
sha1_bytes = mac.doFinal(message.getBytes())
base64 = new Base64()
return new String(base64.encode(sha1_bytes))
}
exports.base64hmacsha256 = base64hmacsha256(args[0], args[1])
endsubmit;
quit;
%put &base64hmacsha256.;
DATA _NULL_ ;
LENGTH cmd $1024 ;
cmd = STRIP(SYMGET("cUrl_exe")) ||
' -U '||"<user:pass>"||' -x <proxy:port> -k'||' -o "' || STRIP(SYMGET("out_file")) ||
'" -H "Host: ' || STRIP(SYMGET("bucket")) || '.s3.amazonaws.com' ||
/* '" -H "Content-Type: ' || STRIP(SYMGET("contentType")) || */
'" -H "Date: '||"'"|| STRIP(SYMGET("dateValue")) ||"'"||
'" -H "Authorization: AWS ' || STRIP(SYMGET("s3Key")) || ':' || STRIP(SYMGET("base64hmacsha256")) ||
'" https://' || STRIP(SYMGET("bucket")) || '.s3.amazonaws.com/' || STRIP(SYMGET("file")) ;
RC = SYSTEM(cmd) ;
PUT cmd= RC= ;
RUN ;
此代码的输出如下所示:
cmd=C:\Apps\cUrl\cUrl.exe -U <user:pass> -x <proxy:port> -k -o "<outfile_path>" -H "Host: <bucket_name>.s3.amazonaws.com" -H "Date: 'Fri, 29 JAN 2016 14:47:15 GMT+1300'" -H "Authorization: AWS <access_key>:<signed_signature>" https://<bucket_name>.s3.amazonaws.com/test.txt
为任何帮助干杯!