Cognito ID Pool always fail if the ID provider URL given with / on web identity federation of Auth0.

Summary

  • 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.

To obtain temporary security credentials from Cognito ID Pool, follow the Identity pools (federated identities) authentication flow. JavaScript sample code is like below.

const client = new CognitoIdentityClient({ region: "us-east-1" });
const getIdCommand = new GetIdCommand({
  IdentityPoolId: "us-east-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  Logins: {
    "AUTH0_DOMAIN.auth0.com": idToken,
  },
});
const cognitoId = await client.send(getIdCommand);
const getCredentialsForIdentityCommand = new GetCredentialsForIdentityCommand(
  {
    IdentityId: cognitoId.IdentityId,
    Logins: {
      "AUTH0_DOMAIN.auth0.com": idToken,
    },
  }
);
const awsCredentials = await client.send(getCredentialsForIdentityCommand);

awsCredentials has a temporary security credentials to access the AWS resources. You can access the AWS resources by the assumed role of authenticated user.

In case of using STS directly

To obtain the temporary security credentials from STS directly, use the AssumeRoleWithWebIdentity.

Without using Cognito ID pool like this, there is no role to assume, you need to follow the Creating a role for web identity or OIDC to create a role.

JavaScript sample code is like below.

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.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam:XXXXXXXXXXXX:oidc-provider/dev-AUTH0_DOMAIN.auth0.com/"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "AUTH0_DOMAIN.auth0.com/:aud": "AUTH0_CLIENT_ID"
                }
            }
        }
    ]
}

You can get a success response.

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.

const getIdCommand = new GetIdCommand({
  IdentityPoolId: "us-east-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  Logins: {
-    "AUTH0_DOMAIN.auth0.com": idToken,
+    "AUTH0_DOMAIN.auth0.com/": idToken,
  },
});

const getCredentialsForIclient. Sendand = new GetCredentialsForIdentityCommand(
  {
    IdentityId: cognitoId.IdentityId,
    Logins: {
-    "AUTH0_DOMAIN.auth0.com": idToken,
+    "AUTH0_DOMAIN.auth0.com/": idToken,
    },
  }
);

You’ll get this error.

{
    "errorType": "NotAuthorizedException",
    "errorMessage": "Invalid login token. Issuer doesn't match providerName",
    "name": "NotAuthorizedException",
    "$fault": "client",
    "$metadata": {
        "httpStatusCode": 400,
        "requestId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
        "attempts": 1,
        "totalRetryDelay": 0
    },
    "__type": "NotAuthorizedException",
    ...snip...
}

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.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s