Я развернул API с помощью AWS API Gateway и пытаюсь получить к нему доступ через устройство iOS. Некоторые конечные точки поддерживают неавторизованных пользователей, и у меня нет проблем с доступом к ним, но другие нет, и я не могу их запросить. Я использую новую функцию Cognito User Pool для аутентификации, которая отлично работает при использовании веб-приложения (или почтальона).
Во-первых, даже несмотря на то, что некоторые конечные точки защищены (как на следующем изображении консоли), когда я развертываю API и генерирую SDK для iOS (Objective-C), я могу прочитать в файле 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
Мне удалось получить правильный токен (проверено с помощью почтальона) и идентификатор пользователя:
2016-12-27 12: 43: 35.760 AskHub [26625: 10037234] AWSiOSSDK v2.4.11 [Debug] Строка 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] Идентификационный идентификатор: 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] Не удалось отправить первоначальный запрос: Error Domain = com.amazonaws.AWSAPIGatewayErrorDomain Code = 1 "(null)" UserInfo = {HTTPBody = {message = Unauthorized; }, HTTPHeaderFields = {type = immutable dict, count = 9, entries => 3: Via = {contents = "XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.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 = "Вт, 27 декабря 2016 г., 11:56:25 GMT"} 10: X-Cache = {contents = "Ошибка облачного интерфейса" } 11: X-Amz-Cf-Id = {contents = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}}}
Я что-то упустил? Поддерживает ли автоматически созданный SDK аутентификацию пула пользователей?