Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Authentication fails with AWS Cognito Identity Pool on Android

I get an NotAuthorizedException:Token is not from a supported provider of this identity pool when I call Amazon.CognitoIdentity.AmazonCognitoIdentityClient.GetIdAsync()

I do not understand why, the token was obtained by authenticating with GoogleSignInApi, and the AWS Identity Pool is configured to federate to the Google authentication provider with the same "Google WebApp Client ID" used to authenticate on the Android device.

enter image description here

Also I've tried to obtain the Google token using 2 different ways

  • using the result of .RequestIdToken() on the GoogleSignInOptions
  • by calling the GoogleAuthUtil.GetToken API

Both tokens are different when inspected, both look like good tokens, and both fail with the same error when given to AmazonCognitoIdentityClient. Clearly the user is authenticated on the Android device, the app is able to get the Email, DisplayName etc...

var googleSignInOptions = new 
GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
   .RequestIdToken("Google WebApp Client ID")
   .RequestEmail()
   .Build();

mGoogleApiClient = new GoogleApiClient.Builder(this)
   .EnableAutoManage(
      this, // FragmentActivity
      this) // OnConnectionFailedListener
   .AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
   .Build();

mGoogleApiClient.Connect();

var result = await Auth.GoogleSignInApi.SilentSignIn(mGoogleApiClient);

// Only need one or the other, trying to figure out which
var idToken = result.SignInAccount.IdToken;
var authToken = await GetGoogleAuthTokenAsync(result.SignInAccount.Email);

var shortLivedAWScredentials = new CognitoAWSCredentials("identity-pool-id", AWSConfigs.RegionEndpoint);
var cognitoClient = new AmazonCognitoIdentityClient(shortLivedAWScredentials,AWSConfigs.RegionEndpoint);

var logins = new Dictionary<string, string>();
logins["accounts.google.com"] = idToken; // same failure if I use authToken

var request = new GetIdRequest();
request.IdentityPoolId = "identity-pool-id";
request.Logins = logins;

var result = await cognitoClient.GetIdAsync(request); // THIS THROWS Amazon.CognitoIdentity.Model.NotAuthorizedException

private async Task<string> GetGoogleAuthTokenAsync(string accountEmail)
{
   Account googleAccount = new Account(accountEmail, GoogleAuthUtil.GoogleAccountType);
   string scopes = "audience:server:client_id:" + "Google WebApp Client ID"
   var token = await Task.Run(() => { return GoogleAuthUtil.GetToken(this, googleAccount, scopes); });
   return token;
}

Notes - Right after the exception, the AWS Console shows the Cognito identity pool grows by 1 unauthenticated identity, no change to the number of google identities enter image description here

like image 242
mipnw Avatar asked Mar 06 '23 14:03

mipnw


1 Answers

Hours of searching and I finally found a solution. Basically AWS Cognito Identity Pool Federation to Google+ is completely broken, but do not despair. What you need to do is Federate to an OpenID provider instead.

First, go to AWS console > IAM > Identity Providers > Create Provider > Provider Type = OpenID Connect > Provider URL = https://accounts.google.com > Audience = "the Google Client ID for Android or iOS you created in the Google Developer Console"

Be careful, do not use the "Google Web App Client ID" for the Audience.

Second, go to AWS Console > Cognito > Federated Identity Pools. Select your Identity Pool, then click "Edit Identity Pool", then navigate to the OpenID tab (not the Google+ tab, don't even use that one it doesn't work). You should now see a checkbox titled "accounts.google.com", check it.

Third, go edit your mobile app source code, and make sure you use the "Google WebApp Client ID" you generated in the Google Developer Console when you build the scopes string used to call GoogleAuthUtil.GetTokenGoogleAuthUtil.GetToken(this, googleAccount, scopes). That is scopes = "audience:server:client_id:" + "webClientId"

Now your call to var result = await cognitoClient.GetIdAsync(request); should succeed.

like image 138
mipnw Avatar answered Mar 10 '23 10:03

mipnw