2012-11-06 114 views
0
2模式OAuth認證(或)消費關鍵的OAuth web服務

我已經在我的web配置2種條腿OAuth的服務,按照本指南: http://drupal.org/node/1827698消費使用Restkit

我敢肯定的是,配置是所有適當的,因爲當我通過Web瀏覽器觸發使用基本URL +服務端點web服務,瀏覽器返回我這個錯誤:

This XML file does not appear to have any style information associated with it. The document tree is shown below. 
<result>The request must be signed</result> 

沒有哪一種認爲它是一個身份驗證錯誤。我想。

現在我有計劃在我的iPhone項目中使用Restkit。我遵循這個指南寫下一個簡單的2條腿OAuth的Web服務請求: https://github.com/RestKit/RestKit/wiki/OAuth-Support-on-RestKit

這是我的代碼:

NSString *urlResource = @""; 
    urlResource = @"/service_endpoint/node"; 
    RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURLString:@"http://mydomain.com/"]; 
    [RKObjectManager setSharedManager:objectManager]; 
    objectManager.client.OAuth1ConsumerKey = @"proper_consumer_key"; 
    objectManager.client.OAuth1ConsumerSecret = @"proper_consumer_secret"; 
    objectManager.client.OAuth1AccessToken = nil; 
    objectManager.client.OAuth1AccessTokenSecret = nil; 
    objectManager.client.authenticationType = RKRequestAuthenticationTypeOAuth1; 
#define USE_GET_REQUEST 0 
#if USE_GET_REQUEST 
    [objectManager.client get:urlResource delegate:self]; 
#else 
    NSDictionary *theParams = nil; 
    NSString *timeStamp = [[NSNumber numberWithInt:(NSTimeInterval)[[NSDate date] timeIntervalSince1970]] stringValue]; 
    theParams = [NSDictionary dictionaryWithObjectsAndKeys:@"1.0", @"oauth_version", @"HMAC-SHA1", @"oauth_signature_method", timeStamp, @"oauth_timestamp", nil]; 
    [objectManager.client post:urlResource 
         params:theParams 
         delegate:self]; 
#endif 

我試着用作爲post表示GET請求更早。我得到一個空的身體沒有任何數據和地方Restkit日誌本,這表明授權問題:

2012-11-06 19:27:46.887 MyProject OAuth[22187:11603] I restkit.network:RKRequest.m:689 Status Code: 401

我意識到Restkit不會以這種方式添加任何參數,因此要求不知道什麼簽名,時間戳和OAuth版本使用。因此,我嘗試使用POST請求的地方,我可以指定這些參數。即使現在我得到一個空的身體和Restkit日誌說這個:

2012-11-06 19:28:03.231 MyProject OAuth[22205:11603] I restkit.network:RKRequest.m:689 Status Code: 404

我不知道我要去哪裏錯了或還有什麼要嘗試!期待在解決此問題方面提供幫助。

編輯: 我實現了一個丟失的回調方法,現在我越來越:

"The request must be signed"

消息。我假設上述設置應該足夠用於OAuth身份驗證,正如在引用的鏈接中提到的那樣,我還應該做些什麼?

觀察

我能看到的RestKit代碼的內幕和OAuth的參數被放入URL請求的HTTP報頭字段。但我不知道的Drupal 7能夠讀取來自HTTP報頭字段此信息,它總是返回我回:

The request must be signed

這意味着,OAuth的參數由Drupal的在第一種情況下不接受,否則會給我下面的錯誤至少:

Invalid Signature

我一直在尋找一些其他的選擇,看看我的使用者密鑰和機密和所有其他設置在服務器端處理得當與否。爲了證實這一點,我從here下載了php OAuth客戶端腳本。從here下載SVN代碼。在這種情況下,當我使用PHP客戶端交叉檢查請求時,我的請求都完全服務於&我通過輸入端點,使用者密鑰和使用者密鑰來取回XML。

我試過的另一件事是允許GCOAuth生成簽名,並在Restkit中生成所有的簽名,並放置一個斷點,以便我可以將HTTP頭字段轉儲到日誌中,而不是將請求發送到服務器的Restkit快速準備好與上面的PHP客戶端相同的格式的URL請求。現在,這個請求觸發的時候,我回來了

Invalid Signature

迴應,這是否也莫名其妙意味着OAuth的參數不Restkit/GCOAuth適當的準備?

感謝, 拉吉

回答

0

我能借在Restkit的類的變化來解決它。根據我在上述問題中提到的觀察,我能夠弄清楚我認爲是某些Web服務器的限制,在這種情況下可以說Drupal 7。幾乎在iOS中遇到的所有OAuth庫中,OAuth身份驗證參數都設置在請求的HTTP頭字段中。

我遇到了PHP client(正如我上面的觀察中提到的那樣),如果我們提供正確的消費者密鑰和消費者機密,它將生成oauth_nonce字符串和時間戳,並且還會在URL的查詢參數中提供oauth_signature。 Restkit的庫中缺少這種功能(我認爲?)。儘管Restkit使用GCOAuth提供的所有信息填充HTTP標題字段,但我覺得我的Drupal 7網絡服務器沒有以某種方式讀取它,或者我使用了錯誤的HTTP標頭字段。我搜索了關於如何傳遞HTTP頭字段中的參數的Drupal 7的文檔,並從那裏讀取它,但我找不到多少幫助,雖然沒有那麼精通。

所以我的解決方案是建立URL請求,就像提到的PHP client那樣。 RKClient & RKRequest類幾乎所有事情都由Restkit在GCOAuth類中完成。我所要做的只是調整,以便將OAuth參數附加到請求URL。我所有的更改都推送到forked code of Restkit in github。我對該OAuth模塊特有的更改通過「// Raj OAuth:」註釋,可以在項目中進行搜索。

下面是我已成功用於觸發和使用web服務的代碼。現在我已經爲RKClient的-get:delegate:方法提供了一個重載的指定方法,我相信在需要的基礎上,可以擴展到所有其他可用的方法。

-(void)triggerOAuthRequest 
{ 
    NSString *urlResource = @""; 
    urlResource = @"/endpoint_path/endpoint.xml"; 
    NSString *baseURL = @"http://your_domain_name.com/path_to_drupal_home_folder/"; 
    NSString *consumerKey = @"YW9h6tUc*************"; 
    NSString *consumerSecret = @"HUS2ALAC*************"; 

    RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURLString:baseURL]; 
    [RKObjectManager setSharedManager:objectManager]; 
    objectManager.client.OAuth1ConsumerKey = consumerKey; 
    objectManager.client.OAuth1ConsumerSecret = consumerSecret; 
    objectManager.client.OAuth1AccessToken = nil; 
    objectManager.client.OAuth1AccessTokenSecret = nil; 
    objectManager.client.authenticationType = RKRequestAuthenticationTypeOAuth1; 
    [objectManager.client get:urlResource 
        delegate:self 
constructOAuthQueryParamsInURL:YES]; 
} 

我還假定,發送該請求是針對我的OAuth參數與在客戶端後,該請求被髮送到服務器的祕密消費者密鑰簽名的事實足夠安全,但URL本身具有查詢參數,我覺得它是安全的,因爲oauth_signature是用祕密消費者密鑰簽名的,只有網絡服務器可以解密並檢查請求是否來自真實來源。

如果您覺得有任何改進的空間,請告訴我。

感謝,

拉吉