4
votes

I am trying to understand amazon cognito and trying list contents of S3 folder after login through facebook. Face book login works fine. When I tap test button (cmdTestS3Tapped) it throws the following error.

I included AmazonClientManager.h,AmazonClientManager.m and Constants.h to the project from examples amazon provided. The constants are given as belllow. Can anybody help me to resolve the issue.

#define AWSAccountID @"MyAccountID"
#define CognitoPoolID @"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
#define CognitoRoleAuth @"arn:aws:iam::MyAccountID:role/Cognito_iOSTestPoolAuth_DefaultRole"
#define CognitoRoleUnauth @"arn:aws:iam::MyAccountID:role/Cognito_iOSTestPoolAuth_DefaultRole"

This is the Role - Cognito_iOSTestPoolAuth_DefaultRole

{
    "Version": "2012-10-17",
    "Statement": [{
        "Action": [
            "mobileanalytics:PutEvents",
            "cognito-sync:*"
        ],
        "Effect": "Allow",
        "Resource": [
            "*"
        ],
        "Effect": "Allow",
        "Action": "s3:*",
        "Resource": "*"
    }]
}

Here is the Trust Relationship

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "unauthenticated"
        }
      }
    }
  ]
}

Here is the code I am using

- (IBAction)cmdLoginWithFB:(id)sender {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    [self disableUI];
    [[AmazonClientManager sharedInstance] loginFromView:self.view withCompletionHandler:^(NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self refreshUI];
        });
    }];
}

-(void)refreshUI {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    //self.browseDataButton.enabled = YES;
    self.cmdLoginWithFB.enabled = YES;
    if ([[AmazonClientManager sharedInstance] isLoggedIn]) {
        self.cmdLoginWithFB.titleLabel.text = @"Link";
        NSLog(@"-----------LOGED IN -------------->");
    }
    else {
        self.cmdLoginWithFB.titleLabel.text = @"Login";
        NSLog(@"-----------NOT LOGED IN -------------->");
    }
    self.cmdLogoutWipe.enabled = [[AmazonClientManager sharedInstance] isLoggedIn];
}


- (IBAction)cmdTestS3Tapped:(id)sender {
    if ([[AmazonClientManager sharedInstance] isLoggedIn]) {
        NSLog(@"-----------LOGED IN -------------->");
        [self testListBucket];
    }
    else {
        NSLog(@"-----------NOT LOGED IN -------------->");
    }
}


- (void)testListBucket {
    AWSS3GetObjectRequest *getObjectRequest = [[AWSS3GetObjectRequest alloc] init];
    getObjectRequest.key = @"image1.jpg";
    getObjectRequest.bucket = @"multix-test";

    NSLog(@"============================================>");

    //default service has been configured previously
    //AWSS3 *s3 = [[AWSS3 new] initWithConfiguration:[AWSServiceManager defaultServiceManager].defaultServiceConfiguration];

     AWSS3 *s3 = [AWSS3 defaultS3];


    [[s3 getObject:getObjectRequest] continueWithBlock:^id(BFTask *task) {
        if(task.error)
        {
            NSLog(@"Error: %@",task.error);
        }
        else
        {
            NSLog(@"Got File");
            NSData *data = [task.result body];
            NSString *urlString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSURL *url = [[NSURL alloc] initWithString:urlString];
            if ([[UIApplication sharedApplication] canOpenURL:url]) {
                [[UIApplication sharedApplication] openURL:url];
            }
        }
        return nil;
    }];
    NSLog(@"============================================>");
}

Error

2014-11-26 20:58:24.048 FBLoginTest[2647:83767] initializing clients...
2014-11-26 20:58:24.055 FBLoginTest[2647:83767] -----------LOGED IN -------------->
2014-11-26 20:58:33.542 FBLoginTest[2647:83767] -----------LOGED IN -------------->
2014-11-26 20:58:33.542 FBLoginTest[2647:83767] ============================================>
2014-11-26 20:58:33.551 FBLoginTest[2647:83767] ============================================>
2014-11-26 20:58:33.554 FBLoginTest[2647:88515] AWSiOSSDKv2 [Verbose] AWSURLRequestSerialization.m line:110 | -[AWSJSONRequestSerializer serializeRequest:headers:parameters:] | Request body: [{"IdentityId":"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"}]
2014-11-26 20:58:34.870 FBLoginTest[2647:88605] AWSiOSSDKv2 [Debug] AWSURLResponseSerialization.m line:85 | -[AWSJSONResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | Response header: [{
    "Content-Length" = 129;
    "Content-Type" = "application/x-amz-json-1.1";
    Date = "Wed, 26 Nov 2014 16:58:34 GMT";
    nnCoection = close;
    "x-amzn-RequestId" = "7558584c-758d-11e4-a92d-11020f90ea0e";
}]
2014-11-26 20:58:34.871 FBLoginTest[2647:88605] AWSiOSSDKv2 [Verbose] AWSURLResponseSerialization.m line:90 | -[AWSJSONResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | Response body: [{"__type":"NotAuthorizedException","message":"Access to Identity 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx' is forbidden."}]
2014-11-26 20:58:34.873 FBLoginTest[2647:88605] AWSiOSSDKv2 [Error] AWSIdentityProvider.m line:212 | __42-[AWSBasicCognitoIdentityProvider refresh]_block_invoke_2 | GetOpenIdToken failed. Error is [Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=8 "The operation couldn’t be completed. (com.amazonaws.AWSCognitoIdentityErrorDomain error 8.)" UserInfo=0x7fd042491650 {__type=NotAuthorizedException, message=Access to Identity 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx' is forbidden.}]
2014-11-26 20:58:34.873 FBLoginTest[2647:88605] AWSiOSSDKv2 [Error] AWSCredentialsProvider.m line:433 | __40-[AWSCognitoCredentialsProvider refresh]_block_invoke293 | Unable to refresh. Error is [Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=8 "The operation couldn’t be completed. (com.amazonaws.AWSCognitoIdentityErrorDomain error 8.)" UserInfo=0x7fd042491650 {__type=NotAuthorizedException, message=Access to Identity 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx' is forbidden.}]
2014-11-26 20:58:34.873 FBLoginTest[2647:88605] Error: Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=8 "The operation couldn’t be completed. (com.amazonaws.AWSCognitoIdentityErrorDomain error 8.)" UserInfo=0x7fd042491650 {__type=NotAuthorizedException, message=Access to Identity 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx' is forbidden.}
3

3 Answers

4
votes

I think the trust relationship is incorrect. It should be

 "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }

Because your users are authenticated with Facebook. The trust relationship you gave is for unauthenticated users.

See Bob's three parts blog for more details about Cognito, Roles and Trust relationship

Part 1 : http://mobile.awsblog.com/post/Tx2UQN4KWI6GDJL/Understanding-Amazon-Cognito-Authentication

Part 2 : http://mobile.awsblog.com/post/Tx2FL1QAPDE0UAH/Understanding-Amazon-Cognito-Authentication-Part-2-Developer-Authenticated-Ident

Part 3 : http://mobile.awsblog.com/post/Tx1OSMBRHZVM9V0/Understanding-Amazon-Cognito-Authentication-Part-3-Roles-and-Policies

3
votes

The error 'Access to Identity is forbidden' is typically caused by a failure to include the token from the login provider (FB) on your credentials provider.

You didn't include the code handling FB login, but I would make sure that you are correctly setting the token on your AWSCognitoCredentials provider and setting that provider as your default.

Sebastien's answer is still important to take note of as you may face an STS error later if you use the incorrect role.

1
votes

Thank you Bob & Sebastien,

The problem was. I forget to put following code in viewdidload

[[AmazonClientManager sharedInstance] resumeSessionWithCompletionHandler:^(NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self refreshUI];
    });
}];