0

我是 Amazon 身份管理的新手,我想通过 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

谢谢,拉吉

4

1 回答 1

0

I found solution for my problem and now I can build canonical & signed query to create a user in Amazon IAM using VB.NET windows application.

Please follow the below steps. 1.Create a VB.NET project and in AppConfig file, add your access & secret key.

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

2.Below is the code to call 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
于 2013-05-13T15:18:36.160 回答