亚马逊网络服务IAM - 创建用户VB.NET - 签名版本2& 4

时间:2013-05-01 09:44:46

标签: amazon

我是Amazon Identity管理的新手,我想通过Windows应用程序创建新用户。我知道使用AWS .NET SDK这是可能的,但我需要使用WSDL或API创建用户。

我需要帮助在VB.NET中为IAM创建AWS IAM签名版本2或4代码。请在下面找到代码,并告诉我所需的更改。

Imports System
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Web
Imports System.Collections.Generic
Imports System.Security.Cryptography
Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim strURL As String
        strURL = "https://iam.amazonaws.com/"
        Dim strTimestamp As String = PercentEncodeRfc3986(DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss'Z'"))

        Dim strParams As String
        strParams = "?AWSAccessKeyId=XXXXXXXX" &
        "&Action=CreateUser" & _
        "&Path=/" & _
        "&UserName=User1" & _
        "&Timestamp=" & strTimestamp & _
        "&SignatureVersion=2" & _
        "&Version=2010-05-08" & _
        "&SignatureMethod=HmacSHA256"

        Dim strStringToSign As String = "GET\nhttps://iam.amazonaws.com\n/\n" & strParams
        strURL = strURL & strParams & "&Signature=" & PercentEncodeRfc3986(HashString(strStringToSign))
        Dim wc As New WebClient()
        Dim strResponse As String
        strResponse = wc.DownloadString(strURL)
        RichTextBox1.Text = strResponse

    End Sub

    Private Function PercentEncodeRfc3986(ByVal str As String) As String
        str = HttpUtility.UrlEncode(str, System.Text.Encoding.UTF8)
        str.Replace("'", "%27").Replace("(", "%28").Replace(")", "%29").Replace("*", "%2A").Replace("!", "%21").Replace("%7e", "~")

        Dim sbuilder As New StringBuilder(str)
        For i As Integer = 0 To sbuilder.Length - 1
            If sbuilder(i) = "%"c Then
                If [Char].IsDigit(sbuilder(i + 1)) AndAlso [Char].IsLetter(sbuilder(i + 2)) Then
                    sbuilder(i + 2) = [Char].ToUpper(sbuilder(i + 2))
                End If
            End If
        Next
        Return sbuilder.ToString()
    End Function
    Private Const PRIVATE_KEY As String = "XXXXXXX"

    Private Function HashString(ByVal StringToHash As String) As String
        Dim Key() As Byte = Encoding.UTF8.GetBytes(PRIVATE_KEY)
        Dim XML() As Byte = Encoding.UTF8.GetBytes(StringToHash)
        Dim myHMACSHA256 As New System.Security.Cryptography.HMACSHA256(Key)
        Dim HashCode As Byte() = myHMACSHA256.ComputeHash(XML)
        Return Convert.ToBase64String(HashCode)
    End Function


End Class

谢谢, 拉吉

1 个答案:

答案 0 :(得分:0)

我为我的问题找到了解决方案,现在我可以建立规范&签名查询,使用VB.NET Windows应用程序在Amazon IAM中创建用户。

请按照以下步骤操作。 1.创建一个VB.NET项目,并在AppConfig文件中添加您的访问权限。秘密密钥。

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="AWSAccessKey" value="YOUR ACCESS KEY"/>
    <add key="AWSSecretKey" value="YOUR SECRET KEY"/>
  </appSettings>
  </configuration>

2.Below是调用SignedHelperRequest

的代码
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Net
Imports System.IO
Imports System.Xml
Imports System.Web
Imports System.Xml.XPath
Imports System.Security.Cryptography
Imports System.Configuration


Public Class Form1

    Dim MY_AWS_ACCESS_KEY_ID As String = ConfigurationManager.AppSettings("AWSAccessKey")
    Dim MY_AWS_SECRET_KEY As String = ConfigurationManager.AppSettings("AWSSecretKey")
    Const DESTINATION As String = "iam.amazonaws.com"

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim helper As New SignedRequestHelper(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY, DESTINATION)
        Dim requestParams As IDictionary(Of String, String) = New Dictionary(Of String, [String])()

        requestParams("Action") = "CreateUser"
        requestParams("Path") = "/"
        requestParams("UserName") = Trim(TextBox1.Text)
        requestParams("SignatureMethod") = "HmacSHA256"
        requestParams("SignatureVersion") = "2"
        requestParams("Version") = "2010-05-08"


        Dim requestUrl As String = helper.Sign(requestParams)
        Dim wc As New WebClient()
        Dim strResponse As String
        strResponse = wc.DownloadString(requestUrl)
        RichTextBox1.Text = ""
        RichTextBox1.Text = strResponse

    End Sub



    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

        Dim helper As New SignedRequestHelper(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY, DESTINATION)
        Dim requestParams As IDictionary(Of String, String) = New Dictionary(Of String, [String])()

        requestParams("Action") = "ListUsers"
        'requestParams("Marker") = ""
        'requestParams("MaxItems") = ""
        requestParams("PathPrefix") = "/"
        requestParams("SignatureMethod") = "HmacSHA256"
        requestParams("SignatureVersion") = "2"
        requestParams("Version") = "2010-05-08"


        Dim requestUrl As String = helper.Sign(requestParams)
        Dim wc As New WebClient()
        Dim strResponse As String
        strResponse = wc.DownloadString(requestUrl)
        RichTextBox1.Text = ""
        RichTextBox1.Text = strResponse

    End Sub
End Class

3.SignedRequestHelper Class

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Web
Imports System.Security.Cryptography

Class SignedRequestHelper
    Private endPoint As String
    Private akid As String
    Private secret As Byte()
    Private signer As HMAC

    Private Const REQUEST_URI As String = "/onca/xml"
    Private Const REQUEST_METHOD As String = "GET"

    Public Sub New(ByVal awsAccessKeyId As String, ByVal awsSecretKey As String, ByVal destination As String)
        Me.endPoint = destination.ToLower()
        Me.akid = awsAccessKeyId
        Me.secret = Encoding.UTF8.GetBytes(awsSecretKey)
        Me.signer = New HMACSHA256(Me.secret)
    End Sub

    Public Function Sign(ByVal request As IDictionary(Of String, String)) As String
        ' Use a SortedDictionary to get the parameters in naturual byte order, as
        ' required by AWS.
        Dim pc As New ParamComparer()
        Dim sortedMap As New SortedDictionary(Of String, String)(request, pc)

        ' Add the AWSAccessKeyId and Timestamp to the requests.
        sortedMap("AWSAccessKeyId") = Me.akid
        sortedMap("Timestamp") = Me.GetTimestamp()

        ' Get the canonical query string
        Dim canonicalQS As String = Me.ConstructCanonicalQueryString(sortedMap)

        ' Derive the bytes needs to be signed.
        Dim builder As New StringBuilder()
        builder.Append(REQUEST_METHOD).Append(vbLf).Append(Me.endPoint).Append(vbLf).Append(REQUEST_URI).Append(vbLf).Append(canonicalQS)

        Dim stringToSign As String = builder.ToString()
        Dim toSign As Byte() = Encoding.UTF8.GetBytes(stringToSign)

        ' Compute the signature and convert to Base64.
        Dim sigBytes As Byte() = signer.ComputeHash(toSign)
        Dim signature As String = Convert.ToBase64String(sigBytes)

        ' now construct the complete URL and return to caller.
        Dim qsBuilder As New StringBuilder()
        qsBuilder.Append("https://").Append(Me.endPoint).Append(REQUEST_URI).Append("?").Append(canonicalQS).Append("&Signature=").Append(Me.PercentEncodeRfc3986(signature))

        Return qsBuilder.ToString()
    End Function

    '
    '         * Sign a request in the form of a query string.
    '         * 
    '         * This method returns a complete URL to use. Modifying the returned URL
    '         * in any way invalidates the signature and Amazon will reject the requests.
    '         

    Public Function Sign(ByVal queryString As String) As String
        Dim request As IDictionary(Of String, String) = Me.CreateDictionary(queryString)
        Return Me.Sign(request)
    End Function

    '
    '         * Current time in IS0 8601 format as required by Amazon
    '         

    Private Function GetTimestamp() As String
        Dim currentTime As DateTime = DateTime.UtcNow
        Dim timestamp As String = currentTime.ToString("yyyy-MM-ddTHH:mm:ssZ")
        Return timestamp
    End Function

    '
    '         * Percent-encode (URL Encode) according to RFC 3986 as required by Amazon.
    '         * 
    '         * This is necessary because .NET's HttpUtility.UrlEncode does not encode
    '         * according to the above standard. Also, .NET returns lower-case encoding
    '         * by default and Amazon requires upper-case encoding.
    '         

    Private Function PercentEncodeRfc3986(ByVal str As String) As String
        str = HttpUtility.UrlEncode(str, System.Text.Encoding.UTF8)
        str.Replace("'", "%27").Replace("(", "%28").Replace(")", "%29").Replace("*", "%2A").Replace("!", "%21").Replace("%7e", "~")

        Dim sbuilder As New StringBuilder(str)
        For i As Integer = 0 To sbuilder.Length - 1
            If sbuilder(i) = "%"c Then
                If [Char].IsDigit(sbuilder(i + 1)) AndAlso [Char].IsLetter(sbuilder(i + 2)) Then
                    sbuilder(i + 2) = [Char].ToUpper(sbuilder(i + 2))
                End If
            End If
        Next
        Return sbuilder.ToString()
    End Function

    '
    '         * Convert a query string to corresponding dictionary of name-value pairs.
    '         

    Private Function CreateDictionary(ByVal queryString As String) As IDictionary(Of String, String)
        Dim map As New Dictionary(Of String, String)()

        Dim requestParams As String() = queryString.Split("&"c)

        For i As Integer = 0 To requestParams.Length - 1
            If requestParams(i).Length < 1 Then
                Continue For
            End If

            Dim sep As Char() = {"="c}
            Dim param As String() = requestParams(i).Split(sep, 2)
            For j As Integer = 0 To param.Length - 1
                param(j) = HttpUtility.UrlDecode(param(j), System.Text.Encoding.UTF8)
            Next
            Select Case param.Length
                Case 1
                    If True Then
                        If requestParams(i).Length >= 1 Then
                            If requestParams(i).ToCharArray()(0) = "="c Then
                                map("") = param(0)
                            Else
                                map(param(0)) = ""
                            End If
                        End If
                        Exit Select
                    End If
                Case 2
                    If True Then
                        If Not String.IsNullOrEmpty(param(0)) Then
                            map(param(0)) = param(1)
                        End If
                    End If
                    Exit Select
            End Select
        Next

        Return map
    End Function

    '
    '         * Consttuct the canonical query string from the sorted parameter map.
    '         

    Private Function ConstructCanonicalQueryString(ByVal sortedParamMap As SortedDictionary(Of String, String)) As String
        Dim builder As New StringBuilder()

        If sortedParamMap.Count = 0 Then
            builder.Append("")
            Return builder.ToString()
        End If

        For Each kvp As KeyValuePair(Of String, String) In sortedParamMap

            builder.Append(Me.PercentEncodeRfc3986(kvp.Key))
            builder.Append("=")
            builder.Append(Me.PercentEncodeRfc3986(kvp.Value))
            builder.Append("&")
        Next
        Dim canonicalString As String = builder.ToString()
        canonicalString = canonicalString.Substring(0, canonicalString.Length - 1)
        Return canonicalString
    End Function
End Class

Class ParamComparer
    Implements IComparer(Of String)
    Public Function Compare(ByVal p1 As String, ByVal p2 As String) As Integer Implements IComparer(Of String).Compare

        Return String.CompareOrdinal(p1, p2)
    End Function

End Class