How do I troubleshoot "401 Unauthorized" errors from an API Gateway REST API endpoint after I've set up an Amazon Cognito user pool?

Last updated: 2021-03-30

I set up my Amazon Cognito user pool as a COGNITO_USER_POOLS authorizer on my Amazon API Gateway REST API. Now I get "401 Unauthorized" errors in the API response. How do I troubleshoot these errors?

Resolution

Note: API Gateway can return 401 Unauthorized errors for a variety of reasons. The following procedure shows how to troubleshoot 401 errors related to COGNITO_USER_POOLS authorizers only.

Check the authorizer's configuration on the API method

1.    In the API Gateway console, on the APIs pane, choose the name of your API.

2.    In the left navigation pane, choose Authorizers under your API.

3.    Review the authorizer's configuration and confirm that the following is true:
The user pool ID matches the issuer of the token.
The API is deployed.
The authorizer works in test mode.

For more information, see Integrate a REST API with an Amazon Cognito user pool.

Note: If you can't invoke your API after confirming the authorizer's configuration on the API method, check the validity of the security token.

Check the validity of the security token

For more information, see How can I decode and verify the signature of an Amazon Cognito JSON Web Token? When you check the validity of the security token, confirm that the following is true:

  • The security token isn't expired.
  • The issuer in the security token matches the Amazon Cognito user pool configured on the API.
  • The ID token and access token string values are valid.
    Note: If the string values are valid, you can then decode the tokens. If the tokens aren't valid, make sure that no spaces were added in the tokens when they were passed in the request header.

Important: If there are no additional scopes configured on the API Gateway method, make sure that you're using a valid ID token. If additional scopes are configured on the API Gateway method, confirm that you're using a valid access token. For more information, see Integrate a REST API with an Amazon Cognito user pool.

Example security token payload

Id token payload:
 {
 "sub": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
 "aud": "xxxxxxxxxxxxexample",
 "email_verified": true,
 "token_use": "id",
 "auth_time": 1500009400,
 "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_example",
 "cognito:username": "janedoe",
 "exp": 1500013000,
 "given_name": "Jane",
 "iat": 1500009400,
 "email": "janedoe@example.com"
 }
Access token payload:
{
    "auth_time": 1500009400,
    "exp": 1500013000,
    "iat": 1500009400,
    "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_example",
    "scope": "aws.cognito.signin.user.admin",
    "sub": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "token_use": "access",
    "username": "janedoe@example.com"
}

Note the following claim names in the example security token payload:

  • token_use indicates the type of token (ID or access token).
  • exp indicates the token's expiration time.
    Note: The exp claim is represented as seconds since the Unix epoch (1970-01-01T0:0:0Z) until the date and time the token expires in Coordinated Universal Time (UTC).
  • auth_time indicates when the token was issued.
  • iss indicates the domain of the user pool that issued the tokens.

Important: Make sure that the token you're using matches the user pool configured on the API Gateway method. If you're still unable to invoke the API, confirm that you're using the authorization header correctly.

If you're using Postman to invoke the API

Use Oauth 2.0 authorization mode to use Amazon Cognito tokens directly. When you set up Oauth 2.0 authorization mode, confirm that the following is true:

  • Grant type is Authorization code or Authorization implicit, following your configuration on the user pool's app client.
  • The callback URL matches the redirected URL configured on the user pool's app client.
  • The Auth URL is in the following format:
https://mydomain.auth.us-east-1.amazoncognito.com/login

Important: Replace mydomain with the domain name that you're using to configure your user pool. Make sure that you enter the correct AWS Region your API is hosted in.

  • Client ID is the user pool's app client ID.
    Note: If a client secret is associated with the user pool's app client, make sure that you specify the client secret in the Authorization tab in the client secret field. If no client secret is associated with the user pool's app client, leave the client secret field blank.
  • Scope is configured as openid.
    Note: The openid scope must be allowed on the user pool's app client as well.
  • The correct Amazon Cognito user pool token endpoint is entered for authorization code flow.

Example Amazon Cognito user pool token endpoint

https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token

Note: Postman might not pass the required content type to the token endpoint, which results in a 405 error. However, you don't receive the 504 error when you use implicit flow.