Python Decorator for Cognito User Pool

Source

We have a Python decorator that is associated with all authenticated calls. The decorator performs the following tasks:

  • Checks whether an access token with the Cognito Username is provided in the request header. If so, it looks up the ID_Mapping_Table for the Cognito Username and passes the Internal User_id to our code.
  • Checks whether the access token contains the client id (but no Cognito Username). In this case, the call is coming from an API request using a valid app client id/secret pair. The decorator looks up the ID_Mapping_Table for the Cognito Client_Id and passes the Internal User_id to our code.
  • In other words, our code protected by this decorator is guaranteed to obtain an Internal user_id and can scope all the processing to that user’s scope.

API Gateway APIs using custom scopes in Amazon Cognito

Source

I want to authorize access to my Amazon API Gateway API resources using custom scopes in an Amazon Cognito user pool. How do I do that?

Short description

Define a resource server with custom scopes in your Amazon Cognito user pool. Then, create and configure an Amazon Cognito authorizer for your API Gateway API to authenticate requests to your API resources.

If you have different app clients that need varying levels of access to your API resources, you can provide differentiated access based on the custom scopes that you define. Consider what levels of granular access the different app clients might need, and then design accordingly.

Resolution

If you haven’t done so already, create these prerequisites:

Add a resource server with custom scopes in your user pool

  1. Open the Amazon Cognito console.
  2. Define the resource server and custom scopes.
  3. After saving your changes, on the Resource servers tab, choose Configure app client settings.
  4. On the App client settings tab, under OAuth 2.0, do the following:
    Under Allowed OAuth Flows, select the Implicit grant check box.
    Under Allowed Custom Scopes, select the check box for the custom scope that you defined.
    Note: Observe that the format for a custom scope is resourceServerIdentifier/scopeName. When a client requests a custom scope in an OAuth 2.0 flow, the request must include the full identifier for the scope in this format.
  5. Choose Save changes.

If your mobile applications have a server side component, use the Authorization code grant flow and Proof Key for Code Exchange (PKCE). With the Authorization code grant flow, the tokens are never exposed directly to an end user, and they are less likely to become exposed.

If your setup doesn’t contain any server-side logic, then you can use the Implicit grant flow. The Implicit grant doesn’t generate refresh tokens, thus helping you to prevent refresh tokens from being exposed to the client. Refresh tokens have a longer validity and are used to retrieve newer ID and access tokens.
Important: Don’t store the refresh tokens in a client-side environment.

For more information, see App client settings overview. For more information on Amazon Cognito user pool OAuth 2.0 grants, see Understanding Amazon Cognito user pool OAuth 2.0 grants.

Create an authorizer and integrate it with your API

To complete these steps, follow the instructions in Integrate a REST API with an Amazon Cognito User Pool.

  1. To create the authorizer, follow the instructions under To create a COGNITO_USER_POOLS authorizer by using the API Gateway console.
    Note: After creation, there’s an option in the console to Test your authorizer. This requires an identity token. To test your setup outside of the console using an access token, see Get a user pool access token for testing later in this article.
  2. To integrate the authorizer with your API, follow the instructions under To configure a COGNITO_USER_POOLS authorizer on methods.
    Note: For OAuth Scopes, enter the full identifier for a custom scope in the format resourceServerIdentifier/scopeName.
  3. Deploy your API.

Get a user pool access token for testing

Use the hosted web UI for your user pool to sign in and retrieve an access token from the Amazon Cognito authorization server. Or, retrieve an access token using the OAuth 2.0 endpoint implementations available in the mobile and web AWS SDKs.

Note: When an app client requests authentication through the hosted web UI, the request can include any combination of system-reserved scopes, or custom scopes that you define in the resource server. If the client doesn’t request any scopes, the authentication server returns an access token that contains all scopes associated with the client. When designing your app client, be sure that it includes the intended scopes in the request to avoid granting unnecessary permissions.

  1. Enter this URL in your web browser:
    https://yourDomainPrefix.auth.region.amazoncognito.com/login?response_type=token&client_id=yourClientId&redirect_uri=redirectUrl
    Note: Replace yourDomainPrefix and region with the values for your user pool. Find them in the Amazon Cognito console on the Domain name tab for your user pool.
    Replace yourClientId with your app client’s ID, and replace redirectUrl with your app client’s callback URL. Find them in the console on the App client settings tab for your user pool. For more information, see LOGIN endpoint.
  2. Sign in to your user pool as the user that you created.
  3. Copy the access token from the URL in the address bar. The token is a long string of characters following access_token=.

Call your API as a test

As a test, call your API using the access token as the value of the authorization header. You can use the Postman app or curl from a command line interface. For more information about curl, see the curl project website.

To use curl, run this command:

curl https://restApiId.execute-api.region.amazonaws.com/stageName/resourceName -H "Authorization: accessToken"

Note: Replace restApiId with the API ID. Replace region with the AWS Region of your API. Replace stageName with the name of the stage where your API is deployed. Replace resourceName with the name of the API resource. Replace accessToken with the token you copied. For more information, see Invoking a REST API in Amazon API Gateway.

If everything is configured correctly, you get a 200 OK response code.