经典 ASP amazon s3 休息授权 [英] Classic ASP amazon s3 rest authorisation

查看:24
本文介绍了经典 ASP amazon s3 休息授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对我在这里做错了什么感到困惑......

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

image/jpeg

x-amz-date:" & strNow & "
/"& AWS_BUCKETNAME & sRemoteFilePath, "
", 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
%>

现在出现错误.

msxml3.dll error '800c0008'

The download of the specified resource has failed.

/s3.asp, line 39

推荐答案

据我所知,我想解释一下 S3 Rest Api 是如何工作的.
首先,您需要了解字符串应该是什么签署亚马逊接受.

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.

格式:

StringToSign = HTTP-Verb + "
" +
    Content-MD5 + "
" +
    Content-Type + "
" +
    Date + "
" +
    CanonicalizedAmzHeaders +
    CanonicalizedResource;

生成签名字符串:

Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) );

传递授权标头:

Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature;

不幸的是,您将逐字节播放,因为没有针对经典 asp 发布的任何 SDK.所以,应该通过阅读整个页面了解 http:///docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html

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

对于要签名的字符串,如您在上面看到的格式,API 保留了三个本机标头.Content-TypeContent-MD5Date.这些标头必须存在于字符串中才能签名,即使您的请求在没有标头名称的情况下它们不是空的,只是它的值.有一个例外,如果 x-amz-date 标头已存在于请求中,则 Date 标头在字符串中必须为空才能签名.然后,如果请求具有规范的亚马逊标头,您应该将它们添加为键值对,例如 x-amz-headername:value.但是,对于多个标头,还需要考虑另一个例外情况.多个标头应合并为一个标头,值以逗号分隔.

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 if x-amz-date header is already exists in the request. Then, If request has canonical amazon headers, you should add them as key-value pairs like x-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.

正确

x-amz-headername:value1,value2

x-amz-headername:value1,value2

错误

x-amz-headername:value1
x-amz-headername:value2

x-amz-headername:value1
x-amz-headername:value2

最重要的是,标头必须按其在字符串中的组升序进行签名.首先是按升序排列的保留标头,然后是按升序排列的规范标头.

Most 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.

我建议使用 DomDocument 生成 Base64 编码字符串的功能.此外,您可以使用 .Net 的互操作(例如 System.Security.Cryptography)代替 Windows 脚本组件(.wsc 文件),利用 System.Text.所有这些互操作性都在当今的 IIS Web 服务器中可用.
因此,作为示例,我编写了以下脚本只是将文件发送到您指定的存储桶.考虑并测试它.
假设本地文件名为 myimage.jpg 并将同名上传到存储桶的根目录.

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 as System.Security.Cryptography to generating keyed hashes more effectively with power of System.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 is myimage.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

image/jpeg

x-amz-date:" & strNow & "
/"& AWS_BUCKETNAME & sRemoteFilePath, "
", 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆