Authentication and Authorization with AWS Cognito

Gunjan Chhetri - Aug 24 - - Dev Community

AWS Cognito offers powerful features for user authentication and authorization. The User Pool in Cognito primarily handles authentication, while the Identity Pool manages authorization by granting users access to required AWS services, providing short-lived IAM credentials. In this article, we will use the User Pool for authentication and demonstrate how to grant required permissions to the logged in user.

Create AWS resources

We will be using CDK to create the required resources namely

  1. Cognito User Pool
  2. Cognito Identity Pool
  3. Kinesis Stream

The full code can be found here - https://github.com/gunjchhetri/cognito-kinesis

Once the User Pool and Identity Pool are created, we would need to create a role that would grant the required permission to put data to the kinesis stream

const authenticatedRole = new iam.Role(
      this,
      "CognitoDefaultAuthenticatedRole",
      {
        assumedBy: new iam.FederatedPrincipal(
          "cognito-identity.amazonaws.com",
          {
            StringEquals: {
              "cognito-identity.amazonaws.com:aud": identityPool.ref,
            },
            "ForAnyValue:StringLike": {
              "cognito-identity.amazonaws.com:amr": "authenticated",
            },
          },
          "sts:AssumeRoleWithWebIdentity"
        ),
        managedPolicies: [
          iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonKinesisFullAccess"),
        ],
      }
    );

Enter fullscreen mode Exit fullscreen mode

The above role is then attached to the identity pool so that the logged in users from user pool would be able to put message to kinesis stream.

 new cognito.CfnIdentityPoolRoleAttachment(
      this,
      "IdentityPoolRoleAttachment",
      {
        identityPoolId: identityPool.ref,
        roles: {
          authenticated: authenticatedRole.roleArn,
        },
      }
    );
Enter fullscreen mode Exit fullscreen mode

UI Integration

For this demo, we will be using a single index.html file where the user will first log in to the Cognito User Pool. The code below will open the default cognito login page.

 const redirectUri = "http://localhost:8000";
const loginUrl = `https://${cognitoDomain}/login?response_type=code&client_id=${clientId}&redirect_uri=${encodeURIComponent(
        redirectUri
      )}`;
      window.location.href = loginUrl;

Enter fullscreen mode Exit fullscreen mode

Once the user logs in to Cognito, they will be redirected back to the application with the token ID attached in the URL, which we can use to get the access token:

 const tokenUrl = `https://${cognitoDomain}/oauth2/token`;
      const body = `grant_type=authorization_code&client_id=${clientId}&code=${code}&redirect_uri=${encodeURIComponent(
        redirectUri
      )}`;
      //const authHeader = "Basic " + btoa(`${clientId}:${clientSecret}`);

      const response = await fetch(tokenUrl, {
        method: "POST",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        body: body,
      }); 

      token = response.json();
      return token;
Enter fullscreen mode Exit fullscreen mode

The access token can then be used to obtain short-lived IAM credentials, which can be used to call the Kinesis stream using the AWS SDK:

AWS.config.region = "AWS_REGION";  

      AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: "Idenitity_Pool_ID",
        Logins: {
          [`cognito-idp.${AWS.config.region}.amazonaws.com/User_Pool_Id`]:
            idToken,
        },
      });

      await AWS.config.credentials.getPromise();
      return AWS.config.credentials;
Enter fullscreen mode Exit fullscreen mode

By leveraging AWS Cognito's User Pool and Identity Pool, we've demonstrated how to securely authenticate users and grant them the necessary permissions to interact with AWS services, such as Kinesis, using short-lived IAM credentials.

. .
Terabox Video Player