Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

s3 TransferUtility 'Failed to federate the tokens.' only when using facebook signin #829

Closed
garrettfritz opened this issue Mar 28, 2019 · 7 comments
Assignees
Labels
cognito Issues with the AWS Android SDK for Cognito mobile client Issues with AWS Mobile's client-side Cognito wrapper

Comments

@garrettfritz
Copy link

garrettfritz commented Mar 28, 2019

Describe the bug
We are using cognito auth for both phone number and facebook login. Once we login, we use the JWT token provided from the awsmobilesdk to authenticate with our API. We also use the mobileSDK to upload to s3 using the bucket setup from the AWSMobileHub.

This is all working fine for phone signup, but when we try to sign in with facebook, we can get everything to work (including getting a valid JWT token) except for uploading to s3, at which point it gives us this error:

2019-03-28 16:35:57.505 21821-21954/app.challengr.challengr W/AWSMobileClient: Failed to federate the tokens.
com.amazonaws.services.cognitoidentity.model.NotAuthorizedException: Invalid login token. Token is expired. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: NotAuthorizedException; Request ID: 3cdee60e-51b2-11e9-8407-ff29f39d835f)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:730)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:405)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212)
at com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient.invoke(AmazonCognitoIdentityClient.java:1477)
at com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient.getId(AmazonCognitoIdentityClient.java:757)
at com.amazonaws.auth.AWSAbstractCognitoIdentityProvider.getIdentityId(AWSAbstractCognitoIdentityProvider.java:172)
at com.amazonaws.mobile.client.AWSMobileClientCognitoIdentityProvider.refresh(AWSMobileClient.java:3395)
at com.amazonaws.auth.CognitoCredentialsProvider.startSession(CognitoCredentialsProvider.java:678)
at com.amazonaws.auth.CognitoCredentialsProvider.refresh(CognitoCredentialsProvider.java:631)
at com.amazonaws.auth.CognitoCachingCredentialsProvider.refresh(CognitoCachingCredentialsProvider.java:509)
at com.amazonaws.mobile.client.AWSMobileClient.federateWithCognitoIdentity(AWSMobileClient.java:1400)
at com.amazonaws.mobile.client.AWSMobileClient.getUserStateDetails(AWSMobileClient.java:914)
at com.amazonaws.mobile.client.AWSMobileClient.waitForSignIn(AWSMobileClient.java:838)
at com.amazonaws.mobile.client.AWSMobileClient.getCredentials(AWSMobileClient.java:356)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4902)
at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1959)
at com.amazonaws.mobileconnectors.s3.transferutility.UploadTask.uploadSinglePartAndWaitForCompletion(UploadTask.java:259)
at com.amazonaws.mobileconnectors.s3.transferutility.UploadTask.call(UploadTask.java:113)
at com.amazonaws.mobileconnectors.s3.transferutility.UploadTask.call(UploadTask.java:58)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
2019-03-28 16:35:57.505 21821-21954/app.challengr.challengr D/AWSMobileClient: waitForSignIn: userState:SIGNED_OUT_FEDERATED_TOKENS_INVALID

To Reproduce
Code to Authenticate using facebook:

private fun attemptFacebookWebLogin() {

        loading_view.visibility = View.VISIBLE
        val builder = Auth.Builder()
        val secret = AWSMobileClient.getInstance().configuration
                .optJsonObject("CognitoUserPool")
                .getString("AppClientSecret")

        val clientId = AWSMobileClient.getInstance().configuration
                .optJsonObject("CognitoUserPool")
                .getString("AppClientId")
        
        AWSMobileClient.getInstance().configuration
        builder.setAppClientId(clientId)
                .setApplicationContext(applicationContext)
                .setAppCognitoWebDomain(getString(R.string.aws_cognito_domain))
                .setSignInRedirect(getString(R.string.aws_signin_redirect_url))
                .setAppClientSecret(secret)
                .setSignOutRedirect(getString(R.string.aws_signout_redirect_url))

        builder.setAuthHandler(object : AuthHandler {

            override fun onSuccess(session: AuthUserSession?) {

                model.username = session?.username
                model.newFacebookUser = true
                val tokenString = session?.accessToken?.jwtToken ?: return
                preferenceData.login(session?.accessToken, null)

                AWSMobileClient.getInstance().federatedSignIn(IdentityProvider.FACEBOOK.toString(), tokenString, object : com.amazonaws.mobile.client.Callback<UserStateDetails> {

                    override fun onResult(result: UserStateDetails?) {

                        checkForExistingUser()

                    }

                    override fun onError(e: Exception?) {}

                })

            }

            override fun onFailure(e: java.lang.Exception?) {}

            override fun onSignout() {}

        })

        cognitoAuth = builder.build();
        cognitoAuth?.getSession()

    }

Code to use transfer utility:

 val transferUtility = TransferUtility.builder()
                .context(this)
                .awsConfiguration(AWSMobileClient.getInstance().configuration)
                .s3Client(AmazonS3Client(AWSMobileClient.getInstance(), Region.getRegion(Regions.US_EAST_1)))
                .build()

Which AWS service(s) are affected?
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.mobile.client.AWSMobileClient
import com.amazonaws.mobile.client.UserState
import com.amazonaws.mobile.client.UserStateDetails
import com.amazonaws.mobileconnectors.s3.transferutility

Expected behavior
We would like to upload to s3 when a user signs in with facebook

Screenshots
N/A

Environment Information (please complete the following information):

  • AWS Android SDK Version: [e.g. 2.6.25]
  • Device: [e.g. Pixel XL, Simulator]
  • Android Version: [e.g. Nougat 7.1.2]
  • Specific to simulators: [e.g. Yes/No]

Additional context
We have almost an identical approach on iOS and it's working great for everything, so we think this might just be an android problem

@BillBunting
Copy link
Contributor

This is very similar to the bug I have been reporting, but my issue is with Google federated sign in with AWSMobileClient using the drop in UI. The exception is almost identical. There are related issues:

#809
#700 (going back to Feb 14)

21 20:15:34.881 25125-25499/com.buntingsoftware.modlist D/AWSMobileClient: getUserStateDetails: token already federated just fetch credentials
2019-03-21 20:15:35.305 25125-25499/com.buntingsoftware.modlist E/CognitoCachingCredentialsProvider: Failure to get credentials
    com.amazonaws.services.cognitoidentity.model.NotAuthorizedException: Unauthenticated access is not supported for this identity pool. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: NotAuthorizedException; Request ID: 9bddd725-4c37-11e9-9a2a-09359f43ba93)
        at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:730)
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:405)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212)
        at com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient.invoke(AmazonCognitoIdentityClient.java:1477)
        at com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient.getId(AmazonCognitoIdentityClient.java:757)
        at com.amazonaws.auth.AWSAbstractCognitoIdentityProvider.getIdentityId(AWSAbstractCognitoIdentityProvider.java:172)
        at com.amazonaws.mobile.client.AWSMobileClientCognitoIdentityProvider.refresh(AWSMobileClient.java:3395)
        at com.amazonaws.auth.CognitoCredentialsProvider.startSession(CognitoCredentialsProvider.java:678)
        at com.amazonaws.auth.CognitoCredentialsProvider.getCredentials(CognitoCredentialsProvider.java:465)
        at com.amazonaws.auth.CognitoCachingCredentialsProvider.getCredentials(CognitoCachingCredentialsProvider.java:480)
        at com.amazonaws.mobile.client.AWSMobileClient.getUserStateDetails(AWSMobileClient.java:911)
        at com.amazonaws.mobile.client.AWSMobileClient.waitForSignIn(AWSMobileClient.java:838)
        at com.amazonaws.mobile.client.AWSMobileClient.getCredentials(AWSMobileClient.java:356)
        at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:5200)
        at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.query(AmazonDynamoDBClient.java:2163)
        at com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.queryPage(DynamoDBMapper.java:2489)
        at com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.queryPage(DynamoDBMapper.java:2464)
        at com.buntingsoftware.modlist.ModListDAOImpl.getModFeed(ModListDAOImpl.java:705)
        at com.buntingsoftware.modlist.modfeed.ModFeedFragment$GetFeedTask.doInBackground(ModFeedFragment.java:344)
        at com.buntingsoftware.modlist.modfeed.ModFeedFragment$GetFeedTask.doInBackground(ModFeedFragment.java:326)
        at android.os.AsyncTask$2.call(AsyncTask.java:304)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)

@minbi minbi self-assigned this Mar 29, 2019
@minbi minbi added cognito Issues with the AWS Android SDK for Cognito mobile client Issues with AWS Mobile's client-side Cognito wrapper labels Mar 29, 2019
@minbi
Copy link
Contributor

minbi commented Mar 29, 2019

Hi @garrettfritz ,

When using federatedSignIn() directly you will be notified in the UserStateListener when the tokens have expired via the enum SIGNED_OUT_FEDERATED_TOKENS_INVALID. You can add a listener via 'addUserStateListener(UserStateListener)`

@garrettfritz
Copy link
Author

garrettfritz commented Mar 29, 2019

Hello @minbi ,

Thanks, but I don't think the token has expired yet since for the purposes of this test, I am trying to upload immediately after the federated signin is successful, (also immediately after UserStateListener returns a signed in state and token that is valid for an hour).

But perhaps I can add a bit more information, I didn't notice this before, but it appears as though AWSMobileClient is clearing all the credentials immediately when I try to upload to S3... this console log is an expanded version of what I sent above, I also am logging at the end that the UserStateListener is ultimately indicating we are now signed out...

2019-03-29 10:25:52.717 28806-29046/app.challengr.challengr D/AWSMobileClient: Inspecting user state details
2019-03-29 10:25:52.718 28806-29046/app.challengr.challengr D/AWSMobileClient: hasFederatedToken: false provider: graph.facebook.com
2019-03-29 10:25:52.718 28806-29046/app.challengr.challengr D/AWSMobileClient: hasFederatedToken: false provider: graph.facebook.com
2019-03-29 10:25:52.718 28806-29046/app.challengr.challengr D/CognitoCachingCredentialsProvider: Clearing credentials from SharedPreferences
2019-03-29 10:25:52.723 28806-29046/app.challengr.challengr D/CognitoCachingCredentialsProvider: Clearing credentials from SharedPreferences
2019-03-29 10:25:52.867 28806-29046/app.challengr.challengr W/AWSMobileClient: Failed to federate the tokens.
com.amazonaws.services.cognitoidentity.model.NotAuthorizedException: Invalid login token. Token is expired. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: NotAuthorizedException; Request ID: b453b117-5247-11e9-be24-ad770a6b25db)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:730)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:405)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212)
at com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient.invoke(AmazonCognitoIdentityClient.java:1477)
at com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient.getId(AmazonCognitoIdentityClient.java:757)
at com.amazonaws.auth.AWSAbstractCognitoIdentityProvider.getIdentityId(AWSAbstractCognitoIdentityProvider.java:172)
at com.amazonaws.mobile.client.AWSMobileClientCognitoIdentityProvider.refresh(AWSMobileClient.java:3395)
at com.amazonaws.auth.CognitoCredentialsProvider.startSession(CognitoCredentialsProvider.java:678)
at com.amazonaws.auth.CognitoCredentialsProvider.refresh(CognitoCredentialsProvider.java:631)
at com.amazonaws.auth.CognitoCachingCredentialsProvider.refresh(CognitoCachingCredentialsProvider.java:509)
at com.amazonaws.mobile.client.AWSMobileClient.federateWithCognitoIdentity(AWSMobileClient.java:1400)
at com.amazonaws.mobile.client.AWSMobileClient.getUserStateDetails(AWSMobileClient.java:914)
at com.amazonaws.mobile.client.AWSMobileClient.waitForSignIn(AWSMobileClient.java:838)
at com.amazonaws.mobile.client.AWSMobileClient.getCredentials(AWSMobileClient.java:356)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4902)
at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1959)
at com.amazonaws.mobileconnectors.s3.transferutility.UploadTask.uploadSinglePartAndWaitForCompletion(UploadTask.java:259)
at com.amazonaws.mobileconnectors.s3.transferutility.UploadTask.call(UploadTask.java:113)
at com.amazonaws.mobileconnectors.s3.transferutility.UploadTask.call(UploadTask.java:58)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
2019-03-29 10:25:52.868 28806-29046/app.challengr.challengr D/AWSMobileClient: waitForSignIn: userState:SIGNED_OUT_FEDERATED_TOKENS_INVALID
2019-03-29 10:25:52.872 28806-29048/app.challengr.challengr V/federatedSignin: userState: SIGNED_OUT_FEDERATED_TOKENS_INVALID
2019-03-29 10:25:52.872 28806-29048/app.challengr.challengr V/federatedSignin: details: {provider=graph.facebook.com, token=...}

@minbi
Copy link
Contributor

minbi commented Mar 29, 2019

2019-03-29 10:25:52.872 28806-29048/app.challengr.challengr V/federatedSignin: details: {provider=graph.facebook.com, token=...}

Can you check that the token in the log matched what you were sending in?

I'm not as concerned about the clear of credentials. This happens during the federation process to ensure there are no straggling pieces of state left before a new set of credentials are ingested.

@garrettfritz
Copy link
Author

Hello @minbi yup they are exactly the same, should they be different?

@minbi
Copy link
Contributor

minbi commented Mar 29, 2019

@garrettfritz Found it...I think. The CognitoAuth library does not return a Facebook token. It returns a Userpools token.

Instead of IdentityProviders.FACEBOOK.toString() pass in
userpoolsLoginKey = String.format("cognito-idp.%s.amazonaws.com/%s", "us-east-1", "YourPoolID");

You can check out our documentation on our recommended approach to what your code currently does Docs

CognitoAuth does not support returning a Facebook token. It has been filed as a feature request to the service team.

@garrettfritz
Copy link
Author

ha! look at that, works perfectly, thank you so much @minbi

~G

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cognito Issues with the AWS Android SDK for Cognito mobile client Issues with AWS Mobile's client-side Cognito wrapper
Projects
None yet
Development

No branches or pull requests

3 participants