经典ASP Amazon S3的休息授权 [英] Classic ASP amazon s3 rest authorisation
问题描述
我对我在做什么错在这里...
困惑 < SCRIPT LANGUAGE =JavaScript的=服务器>
功能GMTNow(){返回新的Date()。toGMTString()}
< / SCRIPT>
<%常量AWS_BUCKETNAME =英国bucketname
常量AWS_ACCESSKEY =GOES HERE
常量AWS_SECRETKEY =秘密
LOCALFILE =使用Server.Mappath(/ test.jpg放在)昏暗sRemoteFilePath
sRemoteFilePath =/files/test.jpg远程路径,注意AWS路径(实际上它们不是真正的路径)是严格区分大小写昏暗strNow
strNow = GMTNow()'GMT日期字符串昏暗StringToSign
StringToSign =替换(PUT \\ n \\ nimage / JPEG \\ n \\ NX-AMZ-日期:&放大器; strNow&安培;\\ N /&放大器; AWS_BUCKETNAME&安培; sRemoteFilePath,\\ n,vbLf)昏暗的签名
签名= BytesToBase64(HMACSHA1(AWS_SECRETKEY,StringToSign))昏暗的授权
授权=AWS与& AWS_ACCESSKEY&安培; :&放大器;签名昏暗AWSBucketUrl
AWSBucketUrl =http://s3.amazonaws.com/与& AWS_BUCKETNAME随着的Server.CreateObject(Microsoft.XMLHTTP)
。开PUT,AWSBucketUrl&安培; sRemoteFilePath,假
.setRequestHeader授权,授权
.setRequestHeader内容类型,图像/ JPEG
.setRequestHeader主机,AWS_BUCKETNAME&安培; .s3.amazonaws.com
.setRequestHeaderX-AMZ-DATE,strNow
GetBytes会。发送(LOCALFILE)'获取本地文件的字节数和发送
如果.STATUS = 200那么成功
回复于&下; A HREF =&放大器; AWSBucketUrl&安培; sRemoteFilePath&安培;TARGET = _blank>上传的文件< / A>中
别人的错误途中发生,考虑错误详细信息的XML字符串
Response.ContentType =文/ XML
回复于.responseText
万一
结束与功能GetBytes会(SPATH)
昏暗的FS,女
集FS =的Server.CreateObject(Scripting.FileSystemObject的)
集合F = fs.GetFile(SPATH)
GetBytes会= f.Size
集合F =什么
集FS =什么
结束功能功能BytesToBase64(varBytes)
用的Server.CreateObject(MSXML2.DomDocument)。的createElement(B64)
.dataType =bin.base64
.nodeTypedValue = varBytes
BytesToBase64 =。文本
结束与
结束功能功能HMACSHA1(VARKEY,varValue)
随着的Server.CreateObject(System.Security.Cryptography.HMACSHA1)
。重点= UTF8Bytes(VARKEY)
HMACSHA1 = .ComputeHash_2(UTF8Bytes(varValue))
结束与
结束功能功能UTF8Bytes(varStr)
随着的Server.CreateObject(System.Text.UTF8Encoding)
UTF8Bytes = .GetBytes_4(varStr)
结束与
结束功能
%GT;
现在得到的错误。
MSXML3.DLL错误'800c0008'指定资源的下载失败。/s3.asp,39行
我想解释一下S3 REST API是如何工作的,据我所知。
首先,你需要学习的内容应该是字符串亚马逊签字接受。
格式:
StringToSign = HTTP动词+\\ n+
内容-MD5 +\\ n+
内容类型+\\ n+
日期+\\ n+
CanonicalizedAmzHeaders +
CanonicalizedResource;
生成签署字符串:
签名= Base64编码(HMAC-SHA1(YourSecretAccessKeyID,UTF-8编码,中(StringToSign)));
传递授权头:
=授权AWS++ AWSAccessKeyId +:+签名;
不幸的是,你会因为没有发布传统的ASP任何SDK发挥逐字节。因此,应该通过读取整个页面了解 的http:/ /docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html
有关串签,你可以在格式见上面,有三个原生头由API保留。 内容类型 内容-MD5 和日期即可。这些头必须是存在的字符串中签甚至你的要求也没有他们没有头名作为空的,只是它的价值。有一个例外,日期
头必须是字符串空签,如果 X-AMZ-日期
头是已经存在在请求中。然后,如果要求有规范的亚马逊的头,你应该将它们添加像键 - 值对的x AMZ-headername:值
。但是,还有另一种例外需要被考虑为多个标题。多个头应结合到一个头用逗号分隔值。
正确
X-AMZ-headername:值1,值
块引用>错误
X-AMZ-headername:数值\\ n
的X AMZ-headername:VALUE2
块引用>最重要,标题必须是按组签署字符串按升序排列。首先,保留与标题升序排列,然后规范用头升序排列。
我推荐使用的
的DomDocument
的功能,生成的Base64 EN codeD字符串。
此外,而不是Windows脚本组件(的.wsc文件)中,你可以使用NET的互操作性展示,如System.Security.Cryptography
与<$的力量更有效地产生键控散列C $ C> System.Text 。所有这些互用性的在今天的IIS Web服务器可用。
因此,作为一个例子,我写了下面的脚本只是将文件发送到斗指定。考虑并进行测试。
假设本地文件名是myimage.jpg
,将与同名桶根上传。&LT; SCRIPT LANGUAGE =JavaScript的=服务器&GT;
功能GMTNow(){返回新的Date()。toGMTString()}
&LT; / SCRIPT&GT;&LT;%
常量AWS_BUCKETNAME =英国bucketname
常量AWS_ACCESSKEY =GOES HERE
常量AWS_SECRETKEY =秘密LOCALFILE =使用Server.Mappath(/ test.jpg放在)昏暗sRemoteFilePath
sRemoteFilePath =/files/test.jpg远程路径,注意AWS路径(实际上它们不是真正的路径)是严格区分大小写昏暗strNow
strNow = GMTNow()'GMT日期字符串昏暗StringToSign
StringToSign =替换(PUT \\ n \\ nimage / JPEG \\ n \\ NX-AMZ-日期:&放大器; strNow&安培;\\ N /&放大器; AWS_BUCKETNAME&安培; sRemoteFilePath,\\ n,vbLf)昏暗的签名
签名= BytesToBase64(HMACSHA1(AWS_SECRETKEY,StringToSign))昏暗的授权
授权=AWS与&amp; AWS_ACCESSKEY&安培; :&放大器;签名昏暗AWSBucketUrl
AWSBucketUrl =https://开头与&amp; AWS_BUCKETNAME&安培; .s3.amazonaws.com随着的Server.CreateObject(MSXML2.ServerXMLHTTP.6.0)
。开PUT,AWSBucketUrl&安培; sRemoteFilePath,假
.setRequestHeader授权,授权
.setRequestHeader内容类型,图像/ JPEG
.setRequestHeader主机,AWS_BUCKETNAME&安培; .s3.amazonaws.com
.setRequestHeaderX-AMZ-DATE,strNow
GetBytes会。发送(LOCALFILE)'获取本地文件的字节数和发送
如果.STATUS = 200那么成功
回复于&下; A HREF =&放大器; AWSBucketUrl&安培; sRemoteFilePath&安培;TARGET = _blank&GT;上传的文件&LT; / A&gt;中
别人的错误途中发生,考虑错误详细信息的XML字符串
Response.ContentType =文/ XML
回复于.responseText
万一
结束与功能GetBytes会(SPATH)
随着的Server.CreateObject(的ADODB.Stream)
.TYPE = 1'adTypeBinary
。打开
.LoadFromFile SPATH
.POSITION = 0
GetBytes会= .Read
。关
结束与
结束功能功能BytesToBase64(varBytes)
用的Server.CreateObject(MSXML2.DomDocument)。的createElement(B64)
.dataType =bin.base64
.nodeTypedValue = varBytes
BytesToBase64 =。文本
结束与
结束功能功能HMACSHA1(VARKEY,varValue)
随着的Server.CreateObject(System.Security.Cryptography.HMACSHA1)
。重点= UTF8Bytes(VARKEY)
HMACSHA1 = .ComputeHash_2(UTF8Bytes(varValue))
结束与
结束功能功能UTF8Bytes(varStr)
随着的Server.CreateObject(System.Text.UTF8Encoding)
UTF8Bytes = .GetBytes_4(varStr)
结束与
结束功能
%GT;
I am confused on what I am doing wrong here...
<script language="javascript" runat="server"> function GMTNow(){return new Date().toGMTString()} </script> <% Const AWS_BUCKETNAME = "uk-bucketname" Const AWS_ACCESSKEY = "GOES HERE" Const AWS_SECRETKEY = "SECRET" LocalFile = Server.Mappath("/test.jpg") Dim sRemoteFilePath sRemoteFilePath = "/files/test.jpg" 'Remote Path, note that AWS paths (in fact they aren't real paths) are strictly case sensitive Dim strNow strNow = GMTNow() ' GMT Date String Dim StringToSign StringToSign = Replace("PUT\n\nimage/jpeg\n\nx-amz-date:" & strNow & "\n/"& AWS_BUCKETNAME & sRemoteFilePath, "\n", vbLf) Dim Signature Signature = BytesToBase64(HMACSHA1(AWS_SECRETKEY, StringToSign)) Dim Authorization Authorization = "AWS " & AWS_ACCESSKEY & ":" & Signature Dim AWSBucketUrl AWSBucketUrl = "http://s3.amazonaws.com/" & AWS_BUCKETNAME With Server.CreateObject("Microsoft.XMLHTTP") .open "PUT", AWSBucketUrl & sRemoteFilePath, False .setRequestHeader "Authorization", Authorization .setRequestHeader "Content-Type", "image/jpeg" .setRequestHeader "Host", AWS_BUCKETNAME & ".s3.amazonaws.com" .setRequestHeader "x-amz-date", strNow .send GetBytes(LocalFile) 'Get bytes of local file and send If .status = 200 Then ' successful Response.Write "<a href="& AWSBucketUrl & sRemoteFilePath &" target=_blank>Uploaded File</a>" Else ' an error ocurred, consider xml string of error details Response.ContentType = "text/xml" Response.Write .responseText End If End With Function GetBytes(sPath) dim fs,f set fs=Server.CreateObject("Scripting.FileSystemObject") set f=fs.GetFile(sPath) GetBytes = f.Size set f=nothing set fs=nothing End Function Function BytesToBase64(varBytes) With Server.CreateObject("MSXML2.DomDocument").CreateElement("b64") .dataType = "bin.base64" .nodeTypedValue = varBytes BytesToBase64 = .Text End With End Function Function HMACSHA1(varKey, varValue) With Server.CreateObject("System.Security.Cryptography.HMACSHA1") .Key = UTF8Bytes(varKey) HMACSHA1 = .ComputeHash_2(UTF8Bytes(varValue)) End With End Function Function UTF8Bytes(varStr) With Server.CreateObject("System.Text.UTF8Encoding") UTF8Bytes = .GetBytes_4(varStr) End With End Function %>
Now getting the error.
msxml3.dll error '800c0008' The download of the specified resource has failed. /s3.asp, line 39
解决方案I'd like to explain how S3 Rest Api works as far as I know.
First, you need to learn what should be the string to sign Amazon accepts.Format :
StringToSign = HTTP-Verb + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedAmzHeaders + CanonicalizedResource;
Generating signed string :
Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) );
Passing authorization header:
Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature;
Unfortunately you'll play byte to byte since there is no any SDK released for classic asp. So, should understand by reading the entire page http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html
For string to sign as you can see above in format, there are three native headers are reserved by the API. Content-Type, Content-MD5 and Date. These headers must be exists in the string to sign even your request hasn't them as empty without header name, just its value. There is an exception,
Date
header must be empty in string to sign ifx-amz-date
header is already exists in the request. Then, If request has canonical amazon headers, you should add them as key-value pairs likex-amz-headername:value
. But, there is another exception need to be considered for multiple headers. Multiple headers should combine to one header with values comma separated.Correct
x-amz-headername:value1,value2
Wrong
x-amz-headername:value1\n
x-amz-headername:value2Most importantly, headers must be ascending order by its group in the string to sign. First, reserved headers with ascending order, then canonical headers with ascending order.
I'd recommend using
DomDocument
functionality to generate Base64 encoded strings. Additionally instead of a Windows Scripting Component (.wsc files), you could use .Net's interops such asSystem.Security.Cryptography
to generating keyed hashes more effectively with power ofSystem.Text
. All of these interoperabilities are available in today's IIS web servers.
So, as an example I wrote the below script just sends a file to bucket you specified. Consider and test it.
Assumed local file name ismyimage.jpg
and will be uploaded with same name to root of the bucket.
<script language="javascript" runat="server"> function GMTNow(){return new Date().toGMTString()} </script>
<% Const AWS_BUCKETNAME = "uk-bucketname" Const AWS_ACCESSKEY = "GOES HERE" Const AWS_SECRETKEY = "SECRET" LocalFile = Server.Mappath("/test.jpg") Dim sRemoteFilePath sRemoteFilePath = "/files/test.jpg" 'Remote Path, note that AWS paths (in fact they aren't real paths) are strictly case sensitive Dim strNow strNow = GMTNow() ' GMT Date String Dim StringToSign StringToSign = Replace("PUT\n\nimage/jpeg\n\nx-amz-date:" & strNow & "\n/"& AWS_BUCKETNAME & sRemoteFilePath, "\n", vbLf) Dim Signature Signature = BytesToBase64(HMACSHA1(AWS_SECRETKEY, StringToSign)) Dim Authorization Authorization = "AWS " & AWS_ACCESSKEY & ":" & Signature Dim AWSBucketUrl AWSBucketUrl = "https://" & AWS_BUCKETNAME & ".s3.amazonaws.com" With Server.CreateObject("MSXML2.ServerXMLHTTP.6.0") .open "PUT", AWSBucketUrl & sRemoteFilePath, False .setRequestHeader "Authorization", Authorization .setRequestHeader "Content-Type", "image/jpeg" .setRequestHeader "Host", AWS_BUCKETNAME & ".s3.amazonaws.com" .setRequestHeader "x-amz-date", strNow .send GetBytes(LocalFile) 'Get bytes of local file and send If .status = 200 Then ' successful Response.Write "<a href="& AWSBucketUrl & sRemoteFilePath &" target=_blank>Uploaded File</a>" Else ' an error ocurred, consider xml string of error details Response.ContentType = "text/xml" Response.Write .responseText End If End With Function GetBytes(sPath) With Server.CreateObject("Adodb.Stream") .Type = 1 ' adTypeBinary .Open .LoadFromFile sPath .Position = 0 GetBytes = .Read .Close End With End Function Function BytesToBase64(varBytes) With Server.CreateObject("MSXML2.DomDocument").CreateElement("b64") .dataType = "bin.base64" .nodeTypedValue = varBytes BytesToBase64 = .Text End With End Function Function HMACSHA1(varKey, varValue) With Server.CreateObject("System.Security.Cryptography.HMACSHA1") .Key = UTF8Bytes(varKey) HMACSHA1 = .ComputeHash_2(UTF8Bytes(varValue)) End With End Function Function UTF8Bytes(varStr) With Server.CreateObject("System.Text.UTF8Encoding") UTF8Bytes = .GetBytes_4(varStr) End With End Function %>
这篇关于经典ASP Amazon S3的休息授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!