2016-04-30 5 views
3

)免責:AWS Signature Version 4を実装しているときにCFのサンプルを見つけることができなかったので、これは「How-To」を意図しています。AWSを翻訳する方法タスク1:シグネチャバージョン4の正式なリクエストを作成

Task 1: Create a Canonical Request for Signature Version 4をCFに実装するにはどうすればよいですか?

概要:改行文字が続くHTTPリクエストメソッド(GET、PUT、POSTなど)、と

  1. スタート。
  2. 標準URIパラメータの後に改行文字を追加します。
  3. 標準クエリ文字列の後に改行文字を追加します。
  4. 改行文字を追加して標準ヘッダーを追加します。
  5. 署名付きヘッダーと改行文字を追加します。
  6. SHA256のようなハッシュ(ダイジェスト)関数を使用して、要求本体のペイロードからハッシュ値を作成します。
  7. 各ステップのコンポーネントを1つの文字列として結合することで完成した標準要求を作成します。
  8. 標準リクエストのダイジェスト(ハッシュ)を、ペイロードをハッシュするのと同じアルゴリズムで作成します。以下は

答えて

4

Task 1: Create a Canonical Request for Signature Version 4

結果のCFScriptの実装です:

f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59 

コード:HTTPリクエストメソッドと

  1. スタート(PUT、GET、 POSTなど)

    requestMethod = "GET"; 
    writeOutput("<br>requestMethod: <code>"& requestMethod &"</code>"); 
    
  2. 改行文字が続く(エンコード)正規のURIパラメータを追加します。

    originalURI = ""; 
    // If the absolute path is empty, use a forward slash (/) 
    originalURI = len(trim(originalURI)) ? originalURI : "/"& originalURI; 
    // Encode URI and preserve forward slashes 
    canonicalURI = replace(encodeRFC3986(originalURI), "%2F", "/", "all"); 
    writeOutput("<br>canonicalURI: <code>"& canonicalURI &"</code>"); 
    
  3. 改行文字

    queryParams = { "Action"="ListUsers", "Version"="2010-05-08" }; 
    
    // a) Encode parameter names and values 
    encodedParams = {}; 
    structEach(queryParams, function(key, value) { 
        encodedParams[ encodeRFC3986(arguments.key) ] = encodeRFC3986(arguments.value); 
    }); 
    
    // b) Sort the encoded parameter in ascending order (ASCII order) 
    encodedKeyNames = structKeyArray(encodedParams); 
    arraySort(encodedKeyNames, "text"); 
    
    // c) Build the canonical query string. Starting with first parameter, append encoded 
    // parameter name, followed by character '=' (ASCII code 61), followed by the encoded value 
    encodedPairs = []; 
    for (key in encodedKeyNames) { 
        arrayAppend(encodedPairs, key &"="& encodedParams[ key ]); 
    } 
    // d) Append the character '&' (ASCII code 38) after each parameter value, except for the last value in the list. 
    canonicalQueryString = arrayToList(encodedPairs, "&"); 
    writeOutput("<br>canonicalQueryString: <code>"& canonicalQueryString &"</code>"); 
    
  4. 続く標準的なクエリ文字列は、改行文字が続く正規のヘッダを、追加。改行文字が続く

    requestHeaders = { "Content-type"= "application/x-www-form-urlencoded; charset=utf-8" 
            , "Host" = "iam.amazonaws.com" 
            , "X-Amz-Date" = "20150830T123600Z" 
           }; 
    
    // a) Convert all header names to lowercase and remove leading spaces and trailing spaces. 
    // Convert sequential spaces in the header value to a single space.   
    cleanedHeaders = {}; 
    structEach(requestHeaders, function(key, value) { 
        headerName = reReplace(trim(arguments.key), "\s+", " ", "all"); 
        headerValue = reReplace(trim(arguments.value), "\s+", " ", "all"); 
        cleanedHeaders[ lcase(headerName) ] = headerValue; 
    }); 
    
    // b) [sort] the (lowercase) headers by character code 
    sortedHeaderNames = structKeyArray(cleanedHeaders); 
    arraySort(sortedHeaderNames, "text"); 
    
    // c) Append the lowercase header name followed by a colon. 
    // Do not sort the values in headers that have multiple values. 
    cleanedPairs = []; 
    for (key in sortedHeaderNames) { 
        arrayAppend(cleanedPairs, key &":"& cleanedHeaders[ key ]); 
    } 
    
    // d) Append new line after each header pair. Should END WITH a new line 
    canonicalHeaderString = arrayToList(cleanedPairs, chr(10)) & chr(10) ; 
    writeOutput("<br> canonicalHeaderString: <code>"& canonicalHeaderString &"</code>"); 
    
  5. 署名ヘッダを追加し、

    // To create the signed headers list, convert all header names to lowercase, 
    // sort them by character code, and use a semicolon to separate the header names. 
    // Note, we already have the sorted names from the canonical header logic (step 4) 
    signedHeaderString = arrayToList(sortedHeaderNames, ";"); 
    writeOutput("<br>signedHeaderString: <code>"& signedHeaderString &"</code>"); 
    
  6. HTTP/HTTPSリクエストのボディにペイロードのハッシュを作成します

    requestPayload = ""; 
    payloadChecksum = lcase(hash(requestPayload , "SHA256")); 
    writeOutput("<br>payloadChecksum: <code>"& payloadChecksum &"</code>"); 
    
  7. コン構造体カノニカル要求は、単一の文字列

    canonicalRequest = requestMethod & chr(10) 
            & canonicalURI & chr(10) 
            & canonicalQueryString & chr(10) 
            & canonicalHeaderString & chr(10) 
            & signedHeaderString & chr(10) 
            & payloadChecksum ; 
    
    writeOutput("<br>canonicalRequest: <pre>"& canonicalRequest &"</pre>"); 
    
  8. 、各ステップから構成要素を組み合わせることによってペイロードを

    requestDigest = lcase(hash(canonicalRequest , "SHA256")); 
    writeOutput("<br>requestDigest: <code>"& requestDigest &"</code>"); 
    
    をハッシュするために使用される同じアルゴリズムで正規のリクエストのダイジェスト(ハッシュ)を作成します

UDF encodeRFC 3986:

/** 
    * URI encoding per RFC 3986: 
    * <ul> 
    *  <li>Unreserved characters that should not be escaped: ALPHA/DIGIT/"-"/"."/"_"/"~" </li> 
    *  <li>Spaces should be encoded as %20 instead of +</li> 
    *  <li>Reserved characters that should be escaped include: ? ## [ ] @ ! $ & ' () * + , ; =</li> 
    * </ul> 
    * 
    * @text String to encode 
    * @returns URI encoded text 
    */ 
    public function encodeRFC3986(required string text) { 
     // Requires CF10+ 
     Local.encoded = encodeForURL(arguments.text); 

     // Undo encoding of tilde "~" 
     Local.encoded = replace(Local.encoded, "%7E", "~", "all"); 
     // Change space encoding from "+" to "%20" 
     Local.encoded = replace(Local.encoded, "+", "%20", "all"); 
     // URL encode asterisk "*" 
     Local.encoded = replace(Local.encoded, "*", "%2A", "all"); 

     return Local.encoded; 
    } 
関連する問題