Search code examples
xamarin.androidamazon-cognitofederated-identity

Authenticating with AWS Cognito Federated Identities fails because user is not authenticated


I am adding proper authentication to an android app that calls AWS-Lambda. The app users will need to sign-up. The app should support public login providers, say Google+ or Facebook. For this purpose I figured I would use AWS Cognito with Federated Identities.

I'm trying to follow the workflow documented by https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-authentication which consists of

  1. GetId
  2. GetOpenIdToken
  3. AssumeRoleWithWebIdentity

In the AWS console I've created an AWS Identity Pool and configured Google+ as an authentication provider. I've disabled unauthenticated access as I need users to always be authenticated.

I'm hitting an issue with calling GetId, the first step in that workflow, it returns and error that informs me that unauthenticated access it not enabled for this identity pool. Right, my user is in the process of authenticating, early in the workflow that user can't yet be authenticated, that's the point isn't it.

Here's the code (Xamarin.Android C#)

using Amazon.CognitoIdentity;

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"] = "id token";

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

var task = cognitoClient.GetIdAsync(request);
var result = await task; 

The GetId calls throws an exception telling me this identity pool does not support unauthenticated access. What part did I misunderstand about authenticating with AWS Cognito with Federated Identities?

Update: So does this mean to keep the AWS Identity Pool disabled for unauthenticated access, I need to create an IAM account with permission to access only that identity pool, and store its credentials inside the mobile app? Just so that my mobile app can do authentication of end-users. If that is indeed how it's done, are there good solutions for storing the access keys inside the mobile app that would block a majority of cheap reverse engineering? If the access key is stored in the mobile app, does that really provide any more security than leaving the identity pool unauthenticated?


Solution

  • I found a solution which does not require calling the following

    1. GetId
    2. GetOpenIdToken
    3. AssumeRoleWithWebIdentity

    Instead do

    var awsCredentials = new CognitoAWSCredentials(
        "Identity Pool ID",
        AWSConfigs.RegionEndpoint);
    awsCredentials.AddLogin("accounts.google.com", token);
    

    Also see this post which explains how to Federate Cognito to Google.