2016-12-27 71 views
1

我已經使用AWS API Gateway部署了一個API,並試圖通過iOS設備訪問它。有些終端支持未經授權的用戶,我無法訪問它們,但其他終端則不支持查詢它們。我使用新的Cognito用戶池功能進行身份驗證,在使用Web應用程序(或郵遞員)時可以正常工作。首先,即使一些端點受到保護(如下面的控制檯圖片所示),當我部署API併爲iOS生成SDK(Objective-C)時,我可以在README文件中讀取: 「所有端點都不需要授權。」API網關爲授權用戶生成的iOS iOS(Objective-C)SDK with Cognito用戶池

enter image description here

然後,當我運行從AWS文檔下面的驗證碼,似乎一切就好了工作:

AWSServiceConfiguration *serviceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionEUWest1 credentialsProvider:nil]; 
AWSCognitoIdentityUserPoolConfiguration *userPoolConfiguration = [[AWSCognitoIdentityUserPoolConfiguration alloc] initWithClientId:ClientId clientSecret:nil poolId:UserPoolId]; 
[AWSCognitoIdentityUserPool registerCognitoIdentityUserPoolWithConfiguration:serviceConfiguration userPoolConfiguration:userPoolConfiguration forKey:@"UserPool"]; 
AWSCognitoIdentityUserPool *pool = [AWSCognitoIdentityUserPool CognitoIdentityUserPoolForKey:@"UserPool"]; 

AWSCognitoIdentityUser *user = [pool getUser]; 
[[user getSession:username password:password validationData:nil] continueWithBlock:^id(AWSTask<AWSCognitoIdentityUserSession *> *task) { 
    if (task.error) { 
     NSLog(@"Could not get user session. Error: %@", task.error); 
    } else if (task.exception) { 
     NSLog(@"Could not get user session. Exception: %@", task.exception); 
    } else { 
     NSLog(@"Successfully retrieved user session data"); 
     AWSCognitoIdentityUserSession *session = (AWSCognitoIdentityUserSession *) task.result; 

     NSMutableString *poolId = [[NSMutableString alloc] initWithString:@"cognito-idp.eu-west-1.amazonaws.com/"]; 
     [poolId appendString:UserPoolId]; 
     NSString *tokenStr = [session.idToken tokenString]; 
     NSDictionary *tokens = [[NSDictionary alloc] initWithObjectsAndKeys:tokenStr, poolId, nil]; 



     CognitoPoolIdentityProvider *idProvider = [[CognitoPoolIdentityProvider alloc] init]; 
     [idProvider addTokens:tokens]; 

     AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionEUWest1 identityPoolId:IdentityPoolId identityProviderManager:idProvider]; 

     [credentialsProvider clearKeychain]; 
     [credentialsProvider clearCredentials]; 

     AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionEUWest1 
                              credentialsProvider:credentialsProvider]; 

     [[credentialsProvider getIdentityId] continueWithBlock:^id _Nullable(AWSTask<NSString *> * _Nonnull task) { 
      if (task.error) { 
       NSLog(@"Could not get identity id: %@", task.error); 
      } else if (task.exception) { 
       NSLog(@"Could not get identity id: %@", task.exception); 
      } else { 
       NSLog(@"Identity id: %@", task.result); 
      } 

      return nil; 
     }]; 
    } 

    return nil; 
}]; 

我實現CognitoPoolIdentityProvider爲this post規定。

@interface CognitoPoolIdentityProvider() 
@property (strong, nonatomic) NSDictionary *tokens; 
@end 

@implementation CognitoPoolIdentityProvider 

    - (AWSTask<NSDictionary *> *)logins { 
     return [AWSTask taskWithResult:self.tokens]; 
    } 

    - (void)addTokens:(NSDictionary *)tokens { 
     self.tokens = tokens; 
    } 

@end 

我設法得到一個正確的令牌(測試使用郵遞員)和用戶ID:

2016-12-27 12:43:35.760 AskHub[26625:10037234] AWSiOSSDK v2.4.11 [Debug] AWSURLResponseSerialization.m line:63 | -[AWSJSONResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | Response body: {"IdentityId":"eu-west-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"} 2016-12-27 12:43:35.766 AskHub[26625:10037234] Identity id: eu-west-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

然而,當我運行下面的代碼打一個受保護的端點,CloudFront的認爲,我未認證。

APIHealthClient *apiClient = [APIHealthClient defaultClient]; 
APIAskHubRequest *initReq = [[APIAskHubRequest alloc] init]; 
initReq.message = @"FIN"; 

NSLog(@"Sending initial request"); 
[[apiClient webhooksAskhubPost:initReq] continueWithBlock:^id(AWSTask *task) { 
    if (task.error) { 
     NSLog(@"Could not send initial request: %@", task.error); 
    } else if (task.exception) { 
     NSLog(@"Could not send initial request: %@", task.exception); 
    } else { 
     NSLog(@"Successfully sent initial request"); 
    } 

    return nil; 
}]; 

的回覆:

2016-12-27 12:56:25.247 AskHub[26784:10046562] Could not send initial request: Error Domain=com.amazonaws.AWSAPIGatewayErrorDomain Code=1 "(null)" UserInfo={HTTPBody={ message = Unauthorized; }, HTTPHeaderFields={type = immutable dict, count = 9, entries => 3 : Via = {contents = "X.X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.cloudfront.net (CloudFront)"} 4 : x-amzn-ErrorType = {contents = "UnauthorizedException"} 5 : Content-Type = {contents = "application/json"} 6 : Content-Length = {contents = "27"} 7 : Connection = {contents = "keep-alive"} 8 : x-amzn-RequestId = {contents = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"} 9 : Date = {contents = "Tue, 27 Dec 2016 11:56:25 GMT"} 10 : X-Cache = {contents = "Error from cloudfront"} 11 : X-Amz-Cf-Id = {contents = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"} } }

我在這裏失去了一些東西?自動生成的SDK是否支持用戶池身份驗證?

+0

我有同樣的問題,你有...我有一個通過我的cognito用戶池授權的api。當我通過郵遞員調用這個api並在用戶池中傳入一個來自用戶的有效的id令牌的「Authorization」頭時,它就可以工作。但是,當我嘗試通過生成的api ios sdk通過ios調用相同的api時,我得到相同的錯誤。我的猜測是,ios中還有一件事尚未安裝?如果我找到它,我會繼續沿着它回到這裏。 –

回答

1

我發現在兩種身份驗證模式之間存在混淆:使用憑證提供程序或僅將JWT標記添加到「授權」標頭參數中(或者您創建自定義參數名稱授權人)。

第一種方法對我不起作用,即使它是我在文檔中找到的唯一一個涉及到使用iOS SDK的方法。第二種方法工作得很好,但爲了能夠在不侵入SDK的情況下使用它,不要忘記在API網關中指定API時添加「授權」標頭。

1

根據我看到的代碼,您正在清除憑據,但從來沒有獲得憑據。快速審查它看起來像你正確設置服務配置和身份驗證,但你永遠不會調用憑據。

如果是這樣,即使您的應用程序將進行身份驗證,憑據提供程序也永遠不會獲取登錄字典。

(您可以在AWS控制檯中驗證這一點,如果您查看要用來訪問資源的identityId,可以查看「登錄」計數。如果爲0,則表示您未登錄)

爲了進行身份驗證,您需要讓憑證提供程序調用您的identityProviderManager「登錄」方法。

當您執行SDK中「憑據」的「getCredentialsForIdentity」時會發生此調用。

通常,序列是GetID,然後是GetCredentialsForId。在IOS SDK中,GetId發生在「getSession」(所以你應該擁有它),並且GetCredentials與「憑據」發生

(請注意,每個SDK中有不同的命名(Mobile Hub vs IOS SDK例如),但重要的是您的憑證提供程序會獲取登錄字典。使用詳細日誌記錄您應該實際看到記錄的「登錄」字典,這將向您證明登錄字典正在提供給憑證提供程序)。

+0

感謝您精確的事情。我試圖調用「憑據」,它似乎工作,因爲我能夠記錄AccessKey,SecretKey和SessionKey。然而,當我設置defaultServiceConfiguration後(使用新的credentialsProvider),然後我調用API,我仍然得到一個UnauthorizedException ... –

+0

你在日誌文件中獲得登錄字典嗎?像這樣:「X-Amz-Target」=「AWSCognitoIdentityService.GetCredentialsForIdentity」; } 2016-12-27 17:09:30.736 KeyCode [3004:122424] AWSiOSSDK v2.4.14 [Debug] AWSURLSessionManager.m line:555 | - [AWSURLSessionManager printHTTPHeadersAndBodyForRequest:] |請求正文: {「Logins」:{「cognito-idp.us-east-1.amazonaws.com \/us-east-1_xxxxxxxxx」:「eyJraWQixxxxxxxxxx long long coded tokenxxxxxj3f2QzWX5o8AVdtDPA」},「IdentityId」:「us-east -1:「} – Bruce0

+0

您是否在aws控制檯中爲有問題的identityId獲得大於0的登錄? – Bruce0

相關問題