AppsDev
AppsDev

Reputation: 12509

AWS SDK for iOS: unable to list the files in an S3 bucket

I followed the firsts steps here to configure credentials and an S3 bucket. Then, in my code, I have:

func setupCredentialsProvider() {
    let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.USEast1, identityPoolId:identityPoolIdStr)
    let configuration = AWSServiceConfiguration(region:.USEast1, credentialsProvider:credentialsProvider)
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration

    AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)
}

func listObjects() {
    let s3 = AWSS3.defaultS3()

    let listObjectsRequest = AWSS3ListObjectsRequest()
    listObjectsRequest.bucket = S3BucketName
    s3.listObjects(listObjectsRequest).continueWithBlock { (task) -> AnyObject! in
        if let error = task.error {
            print("listObjects failed: [\(error)]")
        }
        if let exception = task.exception {
            print("listObjects failed: [\(exception)]")
        }
}

When I run the app and listObjects() is called, I get this error:

listObjects failed: [Error Domain=com.amazonaws.AWSServiceErrorDomain Code=11 "(null)" UserInfo={HostId=, Message=Access Denied, Code=AccessDenied, RequestId=}]

What am I missing?

Upvotes: 5

Views: 2856

Answers (1)

Nick Ager
Nick Ager

Reputation: 1285

If it's anything like the problem I had, your authenticated Cognito user doesn't have permission to access a specific S3 bucket. Reading Understanding Amazon Cognito Authentication Part 3: Roles and Policies gave me the clue I needed, specifically:

When you create your identity pool via the Cognito console, it will create two roles for you, one for authenticated users and one for unauthenticated users, but you can visit the IAM Console and create more roles than just these. You can also modify the existing roles to add support for additional services such as Amazon S3 or Amazon DynamoDB, depending on your use case.

So I decided to modify the created role for authenticated users to allow access to my S3 bucket:

  1. Switch to your IAM console and find a role named something like: xxxx_auth_yyy - the auth substring is the important part as it identifies the role as the one for authenticated users.
  2. Use this role to assign permissions to authenticated users by:
  3. Create a policy (Policies -> Create Policy) to give the access required to the specific bucket.
  4. "Attach" this policy to the authenticated role (Roles -> xxxx_auth_yyy -> Attach Policy).
  5. Your code should now be able to list the files in a specific S3 bucket.

Example policy (step 3):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET_NAME*"
            ]
        }
    ]
}

Upvotes: 2

Related Questions