When you add the API to amplify app, using amplify add api command, GraphQL or REST API will be add. For local environment test, you can use amplify mock api command. However, this command is available only for GraphQL API.
When you mock the API without adding GraphQL API, the command return the error as shown below.
Failed to start API Mocking. Running cleanup tasks.
TypeError: Cannot read property 'stop' of undefined
at APITest.stop (/snapshot/repo/build/node_modules/amplify-util-mock/lib/api/api.js:187:33)
at APITest.start (/snapshot/repo/build/node_modules/amplify-util-mock/lib/api/api.js:150:18)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async start (/snapshot/repo/build/node_modules/amplify-util-mock/lib/api/index.js:18:5)
at async Object.run (/snapshot/repo/build/node_modules/amplify-util-mock/lib/commands/mock/api.js:21:5)
at async Object.executeAmplifyCommand (/snapshot/repo/build/node_modules/amplify-util-mock/lib/amplify-plugin-index.js:47:3)
at async executePluginModuleCommand (/snapshot/repo/build/node_modules/@aws-amplify/cli-internal/lib/execution-manager.js:142:5)
at async executeCommand (/snapshot/repo/build/node_modules/@aws-amplify/cli-internal/lib/execution-manager.js:40:9)
at async Object.run (/snapshot/repo/build/node_modules/@aws-amplify/cli-internal/lib/index.js:117:5)
This error does not describe the actual situation. This is because the mock clean up fails when the no appsync api exists error occurs. For now, I have submitted a Pull Request to show the correct error. I’m sure it will be fixed soon.
If the Provider URL of identity provider is ending with /, Issuer validation of Cognito ID pool always fail.
When the temporary security credentials are created by OpenID Connect (OIDC) ID provider, you need to add separate identity providers for Cognito ID Pool and STS. even if same provider.
Issuing temporary security credentials in IAM for authenticated by OIDC provider.
There are 2 ways of issuing temporary security credentials in IAM for authenticated user by Auth0, using Cognito ID Pool or STS (Security Token Service). When Cognito ID Pool is issuing, the process of credentials issue is almost same, because the Cognito uses STS inside. However, the verification of ID token has difference.
In case of Cognito ID Pool
This article uses a sample code that federated with OpenID Connect (Auth0). First you need to add an identity provider on IAM Identity provider page like below.
Provider type: OpenID Connect
Provider URL: Copy the domain of Auth0 application.
Audience: Copy of Client ID of Auth0.
Do not ended with / for Provider URL.
Next step is to enable the ID provider on the Cognito ID Provider page by creating id pool or using existed pool.
awsCredentials has a temporary security credentials to access the AWS resources. You can access the AWS resources by the assumed role of authenticated user.
const client = new STSClient({ region: "us-east-1" });
const command = new AssumeRoleWithWebIdentityCommand({
RoleArn: "arn:aws:iam::XXXXXXXXXXXX:role/Auth0SampleRole",
RoleSessionName: "Auth0AssumeRoleSession",
WebIdentityToken: idToken,
});
But the Identity provider settings are also required, you must be all right because Cognito ID Pool has been configured already in the previous section.
Please execute this API, you must get following error.
{
"errorType": "InvalidIdentityTokenException",
"errorMessage": "No OpenIDConnect provider found in your account for https://AUTH0_DOMAIN.auth0.com/",
"name": "InvalidIdentityTokenException",
"$fault": "client",
"$metadata": {
"httpStatusCode": 400,
"requestId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"attempts": 1,
"totalRetryDelay": 0
},
"Error": {
"Type": "Sender",
"Code": "InvalidIdentityToken",
"Message": "No OpenIDConnect provider found in your account for https://AUTH0_DOMAIN.auth0.com/",
"message": "No OpenIDConnect provider found in your account for https://AUTH0_DOMAIN.auth0.com/"
},
...snip...
}
This error says the API couldn’t find the OpenID Connect provider. This is strange because the identity provider was configured despite working with Cognito ID Pool correctly.
Answer
In fact, you need to add separate identity provider from Cognito ID Pool. Please try to add identity provider as follows. Don’t forget to add / at the end of provider url.
The role is needed to edit because the identity provider is configured. If this does not work, you may recreate the role.
What do you guess If the provider url ended with / using Cognito ID Pool?
{
"errorType": "NotAuthorizedException",
"errorMessage": "Token is not from a supported provider of this identity pool.",
"name": "NotAuthorizedException",
"$fault": "client",
"$metadata": {
"httpStatusCode": 400,
"requestId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"attempts": 1,
"totalRetryDelay": 0
},
"__type": "NotAuthorizedException",
...snip...
}
“Token is not from a supported provider of this identity pool.” seems to say that the provider’s name of Authentication providers and Logins option of GetId are different. Please change the code to add / as follows and run it.
Now the Cognito ID Pool could find the identity provider, but it mismatches with issuer of ID token due to add /. ID token issued by Auth0 contains iss claim as follows. The iss claim contains /.
{
"iss": "https://AUTH0_DOMAIN.auth0.com/",
}
I think the Cognito ID Pool compare with https://${Identity provider domain}/ and iss claim of ID token. When you add / at the end of provider url, duplicated / prevent the API from verification. Maybe this behavior will change again for ID providers that do not have / in the iss claim.
If you meet those errors, you can resolve the problems with this article’s information.
To open the API for an authenticated user of Auth0, create the API on the Auth0 dashboard.
API settings on Auth0 dashboard
You can use Identifier as you want, the Auth0 recommends API endpoint is preferred to use it. This article uses https://example.com/ as Identifier.
Configure the AWS
Setting Identity providers
After this step, this app will pass the access token issued by Auth0 to the AWS STS. Therefore, you need to add an Auth0 as an identity provider on AWS refer to Creating IAM identity providers.
Go to the “Identity providers” on IAM console, add provider as below.
IAM identity provider settings
Provider type: Open ID Connect
Provider URL: Copy the domain from Auth0 dashboard.
Audience: Copy the API Audience from Auth0 dashboard.
Creating a role to delegate permissions to an AWS service
On the identity providers page, push “Assign role” to create a new role. You need to assign the policies for the AWS resources you want to use. See Creating a role for web identity or OIDC.
This is an example of accessing AWS resources. When requested, this API receives access token, API requests to exchange the access token for AWS temporary credentials.
The aud claim identifies the recipients that the JWT is intended for. When AssumeRoleWithWebIdentity, STS verifies that matching between “aud claim of access token” and “audience of identity provider”.
In general case, when the API responses “Incorrect token audience” message, you need to check the 2 parameters are same. But this sample’s audience parameter is contained in the aud claims correctly.
In fact, STS will always fail validation if the aud token is specified as an array.
The aud claim can contain an array of strings or a single string value defined in RFC 7519. However, STS accepts single string only. When using ID token instead of access token, you can see that STS accepts its.
I contacted AWS support and was told that STS cannot accept an array of aud claims. This behavior is also same for Cognito ID pools.
Alternative Solutions
However, you may not face this situation normally, I show you alternative solutions.
Using ID Token
If your API is public within same domain of frontend app, using ID token is suitable to use. Because the ID token issued by Auth0 contains single string aud claim, STS can accept the token.
Using Lambda Authorizer
In other ways, you can use lambda authorizer to verify the access token yourself.