I'm trying to consume AWS AppSync API using Federated Identities with custom authenticated role but without success.

First, I followed this tutotial to create my client. Then I opened Federated Identities console -> Edit identity pool -> Custom and created a Developer provider name: login.mycompany.myapp and checked Enable access to unauthenticated identities.

After, I followed this one to know how to create custom authentication.

Once you obtain an identity ID and session token from your backend, you will to pass them into the AWS.CognitoIdentityCredentials provider. Here's an example:

AWS.config.credentials = new AWS.CognitoIdentityCredentials({   
    IdentityPoolId: 'IDENTITY_POOL_ID',    
    IdentityId: 'IDENTITY_ID_RETURNED_FROM_YOUR_PROVIDER',
    Logins: {
        'cognito-identity.amazonaws.com': 'TOKEN_RETURNED_FROM_YOUR_PROVIDER'    
    }
});

How can I get IDENTITY_ID_RETURNED_FROM_YOUR_PROVIDER, cognito-identity.amazonaws.com and IDENTITY_ID_RETURNED_FROM_YOUR_PROVIDER? I saw how to do it:

You obtain a token by calling GetOpenIdTokenForDeveloperIdentity. This API must be invoked from your backend using AWS developer credentials.

I checked GetOpenIdTokenForDeveloperIdentity documentation and I created this piece of code:

const AWS = require('aws-sdk');
AWS.config.region = 'us-east-1'; // Region

const cognitoidentity = new AWS.CognitoIdentity();

const params = {
    IdentityPoolId: IDENTITY_POOL_ID',
    Logins: {
        'login.mycompany.myapp': 'sometoken',
    },
};

cognitoidentity.getOpenIdTokenForDeveloperIdentity(params, function(
    err,
    { IdentityId, Token }
) {
    if (err) {
        console.log(err);
    }
    console.log(IdentityId, Token);
}

I got IdentityId and Token. I took these variables and created a Cognito client as follow:

AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: IDENTITY_POOL_ID,
    IdentityId: IdentityId,
    Logins: {
        'cognito-identity.amazonaws.com': Token,
    },
});

const credentials = AWS.config.credentials;

const AWSAppSyncClient = require('aws-appsync').default;
const AUTH_TYPE = require('aws-appsync/lib/link/auth-link').AUTH_TYPE;

// Set up Apollo client
const client = new AWSAppSyncClient({
    url: GRAPHQL_API_URL,
    region: REGION,
    auth: {
        type: AUTH_TYPE.AMAZON_COGNITO_USER_POOLS,
        credentials: credentials,
    },
});

Now, when I make a query

client.hydrated().then(function(client) {
    //Now run a query
    client
        .query({ query: query })
        .then(function logData(data) {
            console.log('results of query: ', data);
        })
        .catch(console.error);
});

I get the error: Network error: Response not successful: Received status code 401. Am I missing some configuration?

Thank you!

Edit: At Federated Identities, I set Unauthenticated role and Authenticated role as follow:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "appsync:GraphQL",
                "mobileanalytics:PutEvents",
                "cognito-sync:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "appsync:GraphQL",
            "Resource": "arn:aws:appsync:*:*:apis/*/types/*/fields/*"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": "appsync:GraphQL",
            "Resource": "arn:aws:appsync:*:*:apis/*"
        }
    ]
}

0 Answers