2013-09-25 42 views
6

好吧,這讓我感到非常緊張。用Objective-C/Cocoa進行AWS身份驗證

我試圖創建一個簡單的AWS S3客戶端,將允許與S3基本交互,但似乎我做錯了什麼,不能弄清楚它是什麼。這可能是非常明顯的,但我沒有看到它。

我的密鑰是正確的,經過測試 - 無結尾的空白等

這個問題似乎是與簽名,它不斷讓我們計算出你所提供的簽名不匹配「請求籤名。檢查您的密鑰和簽名方法'來自Amazon的REST API的錯誤。我創建了各種添加base64和HMAC SHA1生成功能的類別,並且我也瀏覽了各種在線示例,但迄今尚未成功。

之所以沒有使用亞馬遜提供的庫是因爲它的目的是在可可觸摸,我不想砍左右,使其在可可工作。

你可以抓住的所有文件/此處代碼的副本:https://www.dropbox.com/s/8ts9q71dz3uopxp/S3Lite.zip

不過,我下面亞馬遜的周圍認證和我簡單的頭腦文檔,一切都被正確執行。

這裏是我是如何生成簽名:

-(NSString *)signRequest:(NSURLRequest *)request { 
    NSMutableString *sig = [[NSMutableString alloc] init]; 

    // Request Method 
    [sig appendFormat:@"%@\n", [request HTTPMethod]]; 

    // Content MD5 
    [sig appendFormat:@"%@\n", [[request HTTPBody] MD5String]]; 

    // Content Type 
    [sig appendFormat:@"%@\n", [request valueForHTTPHeaderField:@"Content-Type"]]; 

    // Date 
    [sig appendFormat:@"%@\n", [request valueForHTTPHeaderField:@"Date"]]; 

    // Canonicalized Headers 
    [sig appendFormat:@"%@\n", @""]; // Empty for now 

    // Canonicalized Resource 
    [sig appendFormat:@"%@", [NSString stringWithFormat:@"/%@%@", _bucket, request.URL.path]]; 

    NSString *encodedString = [[[sig dataUsingEncoding:NSUTF8StringEncoding] hmacSHA1SignatureWithKey:_secretKey] base64String]; 

    return [[NSString alloc] initWithFormat:@"AWS %@:%@", _accessKey, encodedString]; 
} 

這裏是你如何去使用它試圖執行一個簡單的PUT請求。

#import "S3Lite.h" 

S3Lite *aws = [[S3Lite alloc] initWithAccessKey:@"<access key>" 
            secretKey:@"<secret key>" 
            bucketName:@"<bucket name>" 
             region:kAmazonS3EUWest1Region 
             useSSL:NO]; 

NSData *file = [[NSData alloc] initWithContentsOfFile:@"<path to a file>"]; 

[aws putObjectWithData:file inPath:@"aRandomFile.png" withContentType:nil]; 

任何幫助正確的方向將不勝感激。

小號

+0

我不能真正的幫助,因爲我不太瞭解S3的「協議」,但看了一下java庫JetS3t?你可以試着看看他們是如何在那裏做到的。 http://jets3t.s3.amazonaws.com/downloads.html –

+0

@thibaultd我看過其他各種圖書館,從我所看到的,我的班級幾乎是一樣的。只是似乎無法找到問題 – SeanNieuwoudt

+0

我做了一些基於http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html的單元測試,當我的代碼通過它們時,一切正常。 –

回答

8

即使你不能夠使用AWS SDK適用於iOS直接,它是開源的,你可能從這裏檢查的要求籤署代碼得到一些想法:

https://github.com/aws/aws-sdk-ios/blob/master/AWSCore/Authentication/AWSSignature.m

+1

這看起來像是要走的路,至少使用AmazonAuthUtils進行簽名功能 –

+1

該鏈接不再有效,因爲亞馬遜顯然已經改變了SDK結構,但檢查其代碼的內部看起來似乎有價值,因爲您可以看到他們如何編碼字符串。 GitHub中的當前操作路徑是aws-sdk-ios/AWSCore/Authentication/AWSSignature.m – Cindeselia

+0

已更新。感謝您的提醒。 –

1

當請求中缺少相應的頭文件時,您需要確保在該字符串中包含空值(例如Content-MD5對於PUT請求是可選的,對GET請求無意義 - 您應該只將它的值包含在字符串中如果您的請求中包含該標頭,則進行簽名對S3的API調用)。

+0

我很確定訂購是正確的? 80列的S3 - 96的S3Lite.m – SeanNieuwoudt

+0

對不起,我的壞,你正在使用正確的順序。我會更新我的答案。無論如何請檢查第二部分,因爲它可能是您獲得與S3生成的簽名不同的原因。 – dcro

1

目前我基於AFNetworking 1.0(由於與舊操作系統的兼容性)制定S3客戶端框架。框架本身仍在開發中,但所有AWS4-HMAC-SHA256的請求籤名方法已經實現並正在運行。您可以在github上找到的框架:https://github.com/StudioIstanbul/SIAFAWSClient

隨意叉它和實現的功能,所以我們可以在它一起工作。目前所有基本的S3請求都已執行。 (NSMutableURLRequest *)要求函數自己的代碼:(* NSString的)AuthorizationHeaderStringForRequest -

當然你也可以只是我複製。目前AWS文檔並不是很好,因爲它缺少創建簽名密鑰的一些步驟。