2013-05-01 20 views
0

我是亚马逊身份管理的新手,我想通过Windows应用程序创建新用户。我知道使用AWS .NET SDK这是可能的,但我需要使用WSDL或API创建用户。亚马逊网络服务IAM - 创建用户VB.NET - 签名版本2和4

我需要帮助在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 

感谢, 拉吉

+0

我很好奇,为什么你需要做到这一点,而无需使用AWS的SDK。净。有没有关于它的东西不适合你的环境? – 2013-05-17 06:20:57

+0

要求是使用Web服务和业务不想在prod服务器上安装SDK。 – Raj 2014-06-25 21:55:12

回答

0

,我发现我的问题的解决方案,现在我可以建立规范&签订查询创建使用VB.NET Windows应用程序在亚马逊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类

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