2

AWS API Gateway を使用して API をデプロイしましたが、iOS デバイスからアクセスしようとしています。一部のエンドポイントは無許可のユーザーをサポートしており、アクセスに問題はありませんが、他のエンドポイントはサポートしておらず、クエリを実行できません。Web アプリケーション (または郵便配達員) を使用する場合に正常に動作する認証用の新しい Cognito ユーザー プール機能を使用します。

まず、一部のエンドポイントは保護されていますが (コンソールの次の図のように)、API をデプロイして iOS (Objective-C) 用の SDK を生成すると、README ファイルを読み取ることができます。承認は必要ありません。」

ここに画像の説明を入力

次に、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 を実装しました。

@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

適切なトークン (postman を使用してテスト済み) とユーザー ID を取得できました。

2016-12-27 12:43:35.760 AskHub[26625:10037234] AWSiOSSDK v2.4.11 [デバッグ] AWSURLResponseSerialization.m 行:63 | -[AWSJSONResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | 応答本文: {"IdentityId":"eu-west-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"} 2016-12-27 12:43:35.766 AskHub[26625:10037234] ID 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] 最初のリクエストを送信できませんでした: エラー Domain=com.amazonaws.AWSAPIGatewayErrorDomain Code=1 "(null)" UserInfo={HTTPBody={ message = Unauthorized; }, HTTPHeaderFields={type = immutable dict, count = 9, entries => 3: Via = {contents = "XX 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 = "

ここで何か不足していますか?自動生成された SDK はユーザー プール認証をサポートしていますか?

4

2 に答える 2

2

ここで、資格情報プロバイダーを使用するか、JWT トークンを "Authorization" ヘッダー パラメーター (またはオーソライザーの作成時に指定した場合はカスタム パラメーター名) に追加するという 2 種類の認証モードの間に混乱があることがわかりました。

最初の方法は、iOS SDK の使用に関してドキュメントで見つけた唯一の方法ですが、うまくいきませんでした。2 番目の方法は問題なく機能しますが、SDK をハッキングせずに使用できるようにするには、API Gateway で API を指定するときに「Authorization」ヘッダーを追加することを忘れないでください。

于 2017-01-02T16:02:23.493 に答える