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

5 minute read
0

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 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, then check the validity of the security token.

Check the validity of the security 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 and using Amazon Cognito custom scopes in API Gateway.

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 that 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 still receive 401 errors, make sure that your resource policies aren't blocking the request.

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 that 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, then 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, then 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 can result in a 405 error. However, you don't receive the 504 error when you use implicit flow.


Related information

Secure API access with Amazon Cognito federated identities, Amazon Cognito user pools, and Amazon API Gateway

How can I decode and verify the signature of an Amazon Cognito JSON Web Token?

Control access to a REST API using Amazon Cognito user pools as authorizer

AWS OFFICIAL
AWS OFFICIALUpdated 2 years ago
4 Comments

Hi! I had a different solution for this 401 problem when using a Federated Identity Pool. I had to enable ALLOW_CUSTOM_AUTH as Authentication flow.

profile picture
replied 9 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 9 months ago

Remember to add scopes on the API gateway route itself. Resources, select path, method request(edit) That was my problem

Dan
replied 5 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 5 months ago