1

I'm building an Android app that connects to an Amazon S3 bucket and retrieves mp3 files stored within. This is my first time using Google Sign-in, and it's for a (hopefully) production app, and I want to do it properly.

I've followed all the directions here and have successfully received an ID Token by calling GoogleSignInAccount.getIdToken().

I have then used Amazon's directions for OpenID Connect providers here and used this code:

// Initializing the Amazon Cognito credentials provider

CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider (
    getApplicationContext(),
    "us-east-1:220fe85c-fcc9-4ecc-b923-1357e1380fde", // Example Identity Pool ID
    Regions.US_EAST_1 // Example Region
);

Map<String, String> logins = new HashMap<String, String>();
logins.put("accounts.google.com", idToken);
credentialsProvider.setLogins(logins);

to login. However, nothing is showing up in my Identity Pool. I'm wondering whether it's some confusion on my part in regards to which Client ID I am using. When I created the project on the Google Developer console, I received two ID's. One for a Web Application, and one for Android.

As per Google's instructions here, I passed the Web client ID to the requestIdToken method when I created the GoogleSignInOptions object, and the Android ID to the Identity Pool, like this:

enter image description here

I removed all the other numbers after the hyphen, as the example calls for a smaller ID, but for the record, neither version works. The original was like:

1034544032360-77XXXkoq9XXkdXXsj82uhdXXXbqii6t2.apps.googleusercontent.com

Except when I test my app, It seems to be successful, no errors are thrown, but no new identities are logged in my identity pool.

What am I missing? I would really appreciate a nudge in the right direction.

Jaidyn Belbin
  • 335
  • 5
  • 15
  • Please read http://stackoverflow.com/questions/36230655/google-authentication-in-android-unity-plugin to see if it can help or not – BNK Jun 27 '16 at 09:11
  • @BNK the answerer posted the same code I have above. I still don't understand how to use it. – Jaidyn Belbin Jun 27 '16 at 09:16
  • Since I cannot test with Amazon web service, so I think you should contact him – BNK Jun 27 '16 at 09:21
  • However, from [here](http://docs.aws.amazon.com/cognito/latest/developerguide/google.html), I think you will get `audience:server:client_id:YOUR_GOOGLE_CLIENT_ID` from the Amazon Cognito Console home page – BNK Jun 27 '16 at 09:25
  • Where is "post it..."? In the link of Amazon documentation? – BNK Jun 28 '16 at 13:08
  • No, in the Google docs. I might be onto something, I'll update my question if I have any success... – Jaidyn Belbin Jun 29 '16 at 03:00
  • Ah, that server can be one of your servers or other servers, or event your android app as you have seen my code in http://stackoverflow.com/questions/33998335/how-to-get-access-token-after-user-is-signed-in-from-gmail-in-android (you can see more at comments between me and @scottyab ). But if your app can get the access token at `String token = GoogleAuthUtil.getToken(getApplicationContext(), accounts[0].name, "audience:server:client_id:YOUR_GOOGLE_CLIENT_ID");`, you don't have to send auth code to a server to exchange for access token – BNK Jun 29 '16 at 03:15
  • However, since I cannot test with Amazon WS, so IMO you should contact with the OP of http://stackoverflow.com/questions/36230655/google-authentication-in-android-unity-plugin as I commented yesterday – BNK Jun 29 '16 at 03:17

2 Answers2

0

Is that code you gave the extent of your logging in? The Cognito Android SDK gets credentials lazily, setting logins alone won't do anything. Try adding a credentialsProvider.refresh(); after that.

Jeff Bailey
  • 5,427
  • 1
  • 18
  • 28
  • Yes, thanks. I just figured out the problem yesterday. I should probably update my answer for future references. Cheers – Jaidyn Belbin Jul 21 '16 at 08:52
0

Okay, I solved it finally; there were a few things I missed.

Firstly, as Jeff Bailey mentioned, I wasn't calling credentialsProvider.refresh() after I had set the login token, like this:

private void setCredentials(String token) {

        Map<String, String> logins = new HashMap<>();
        logins.put("accounts.google.com", token);
        credentialsProvider.withLogins(logins);
}

However, that method requires a network request, so that had to be called from an Async task.

Secondly, I used different code to get an ID token from Google, instead of GoogleSignInAccount.getIdToken. See below:

private class GetAndSetGoogleToken extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {

            try {

                GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());

                AccountManager am = AccountManager.get(getApplicationContext());
                Account[] accounts = am.getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);

                token = GoogleAuthUtil.getToken(getApplicationContext(), accounts[0].name,
                        "audience:server:client_id:" + serverClientId);

            } catch(GoogleAuthException ex) {
                Log.d(TAG, "GoogleAuthException has been thrown by GetAndSetGoogleToken!");

            } catch(IOException ex2) {

                Log.d(TAG, "IOException has been thrown by GetAndSetGoogleToken!");
            }

            return token;
        }

        @Override
        protected void onPostExecute(String token) {

            // Passing the ID Token as an Extra to the Intent and starting a new Activity.
            goToNextActivity(token);

            super.onPostExecute(token);
        }
    }

Finally, I hadn't modified my IAM Trust Policies to recognise accounts.google.com as a trusted entity. Once doing so, they looked like this:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": [
          "cognito-identity.amazonaws.com",
          "accounts.google.com" // I needed to add this
        ]
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:xxxx2e4a-4cf6-4121-aa16-xxxx53374a49"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}

Having done all that, it worked fine.

Hope this helps someone; it doesn't seem to be a well documented use-case unfortunately.

Jaidyn Belbin
  • 335
  • 5
  • 15