AWS Cognito Authentication + AWS Mobile Client + API Gateway + S3 Bucket

879 views Asked by At

I built a login screen for my app using AWSCognitoAuth, exactly like in one of the provided examples (https://github.com/awslabs/aws-sdk-ios-samples/tree/master/CognitoAuth-Sample). This works fine - it shows the login screen in an instance of SFSafariViewController where the user just logs in using regular username + passwort, or through Facebook or Google. So after this authentication, I get the access and refresh tokens which I can then use for fetching data from my API, which is routed through AWS API Gateway. The corresponding AWS API Gateway routes are configured to use "User Pools" authorization, instead of "IAM".

But now I need to download some files from a S3 bucket, which is not public. So what needs to be done, is to get temporary AWS Credentials and access the bucket using them. The AWSMobileClient library together with the S3 Transfer Utility are able to do that. But my problem is, I don't know how to tell the AWSMobileClient about the fact, that the user has now signed in .AWSMobileClient is initialized in the appDelegate's didFinishLaunching:withOptions like this:

    let serviceConfiguration = AWSServiceConfiguration(
        region: .EUWest1,
        credentialsProvider: AWSMobileClient.sharedInstance().getCredentialsProvider()

    )

    //create a pool
    let configuration = AWSCognitoIdentityUserPoolConfiguration.init(clientId: CognitoIdentityUserPoolAppClientId, clientSecret: CognitoIdentityUserPoolAppClientSecret, poolId: CognitoIdentityUserPoolId)
    AWSCognitoIdentityUserPool.register(with: serviceConfiguration, userPoolConfiguration: configuration, forKey: AWSCognitoUserPoolsSignInProviderKey)


    AWSServiceManager.default().defaultServiceConfiguration = serviceConfiguration

    AWSFacebookSignInProvider.sharedInstance().setPermissions(["public_profile", "email"])
    AWSSignInManager.sharedInstance().register(signInProvider: AWSFacebookSignInProvider.sharedInstance())

    return AWSMobileClient.sharedInstance().interceptApplication(
        application,
        didFinishLaunchingWithOptions: launchOptions)

The thing is, when I completely close the app after doing the AWSCognitoAuth signin and reopen it, the AWSMobileClient somehow finds the session and the credentials are fetched properly and the file from the bucket gets loaded. But I need to somehow trigger this manually after the user signs in, I cannot force the user to quit and reopen the app, not in 2018... I have been debugging this now for a long time and was digging through the AWSMobileClient framework, trying to find how to hook those two together, but with no success. How can I do it?

1

There are 1 answers

1
TaiT's On

But now I need to download some files from a S3 bucket, which is not public. So what needs to be done, is to get temporary AWS Credentials and access the bucket using them. The AWSMobileClient library together with the S3 Transfer Utility are able to do that. But my problem is, I don't know how to tell the AWSMobileClient about the fact, that the user has now signed in .AWSMobileClient is initialized in the appDelegate's didFinishLaunching:withOptions

Did you already try to use Pre-signed url? It is meant to cover your requirements. It allows temporary access to aws resources, in your case get access on S3 bucket.

You have samples using iOS sdk here, check the S3TransferUtility-Sample.

S3TransferUtility-Sample (Swift, Objective-C). This is a sample mobile application that demonstrates how to use the Amazon S3 PreSigned URL Builder to download / upload files in background. Involved AWS Services are:

  • Amazon S3 Amazon
  • Cognito Identity

Hope it helps!