AWS Big Data Blog

Use Amazon QuickSight Federated Single Sign-On with Amazon Cognito User Pools

AWS recently released federated single sign-on to Amazon QuickSight, as announced on the Amazon QuickSight Now Supports Federated Single Sign-On Using SAML 2.0 post. However, SAML 2.0 is not the only way to federate users for Amazon QuickSight.

Amazon Cognito user pools are full-fledged identity providers (IdP) that you can use to maintain a user directory. The directory can scale to hundreds of millions of users and also add sign-up and sign-in support to your mobile or web applications.

You can provide access from an Amazon Cognito user pool to Amazon QuickSight with IAM identity federation in a serverless way. This solution uses Amazon API Gateway and AWS Lambda as a backend fronted by a simple web app. New features such as Amazon Cognito user pools app Integration make it even easier to add sign-in and sign-up logic to your application and federation use cases.

Solution architecture

Here’s how you can accomplish this solution.

In this scenario, your web app hosted on Amazon S3 integrates with Amazon Cognito User Pools to authenticate users. It uses Amazon Cognito Federated Identities to authorize access to Amazon QuickSight on behalf of the authenticated user, with temporary AWS credentials and appropriate permissions. The app then uses an ID token generated by Amazon Cognito to call API Gateway and Lambda to obtain a sign-in token for Amazon QuickSight from AWS Sign-In Federation. With this token, the app redirects access to Amazon QuickSight:

  1. The Amazon Cognito hosted UI provided by the app integration domain performs all sign-in, sign-up, verification, and authentication logic for the web app. This allows you to register and authenticate users.
  2. After a user is authenticated with a valid user name and password, an OpenID Connect token (ID token) is sent to Amazon Cognito Federated Identities. The token retrieves temporary AWS credentials based on an IAM role with “quickSight:CreateUser” permissions. These credentials are used to build a session string that is encoded into the URL https://signin.aws.amazon.com/federation?Action=getSigninToken.
  3. The ID token, along with the encoded URL, is sent to API Gateway, which in turn verifies the token with a user pool authorizer to authorize the API call.
  4. The URL is passed on to a Lambda function that calls the AWS SSO federation endpoint to retrieve a sign-In token.
  5. The token is sent back to the application.
  6. The application calls the federation endpoint at https://signin.aws.amazon.com/federation?Action=login with the valid sign-in token.
  7. AWS SSO processes the federation request, authenticates the user, and forwards the authentication token to Amazon QuickSight, which then uses the authentication token and authorizes user access.

How can you use, configure and test this serverless solution in your own AWS account? I created a simple SAM (Serverless Application Model) template that can be used to spin up all the resources needed for the solution.

Implementation steps

Using the AWS CLI, create an S3 bucket in the same region in which to deploy all resources:

aws s3 mb s3://<bucket-name> --region <AWS Region>

Download and unzip the following file to your desktop:

https://s3.amazonaws.com/aws-bigdata-blog/artifacts/cognito2quicksight/cognito2quicksight.zip

You could also clone the aws-cognito-quicksight-auth GitHub repository instead.

Then, execute a couple of commands in a terminal or command prompt from inside the uncompressed folder where all files are located, referring to the S3 bucket created earlier:

aws cloudformation package --template-file quicksight.yaml --output-template-file quicksight-output.yaml --s3-bucket <S3 Bucket> 

Next, execute the following command, supplying the path to the quicksight-output.yaml file:

aws cloudformation deploy --template-file /Users/<full path>/quicksight-output.yaml --stack-name CognitoQuickSight --capabilities CAPABILITY_IAM

AWS CloudFormation automatically creates and configures the following resources in your account:

  • Amazon CloudFront distribution
  • S3 static website
  • Amazon Cognito user pool
  • Amazon Cognito identity pool
  • IAM role for authenticated users
  • API Gateway API
  • Lambda function

You can follow the progress of the stack creation from the CloudFormation console. View the Outputs tab for the completed stack to get the identifiers of all created resources. You could also execute the following command with the AWS CLI:

aws cloudformation describe-stacks --query 'Stacks[0].[Outputs[].[OutputKey,OutputValue]]|[]' --output text --stack-name CognitoQuickSight

Use the information from the console or CLI command to replace the related resource identifiers in the file “auth.js”.

In the Amazon Cognito User Pools console, select the pool named QuickSightUsers generated by CloudFormation.

Under App integration, choose Domain name and create a domain. Domain names must be unique to the region. Add the domain to the “auth.js” file accordingly:

Choose App integration, App client settings and then select the option Cognito User Pool. Add the CloudFront distribution address (with https://, as SSL is a requirement for the callback/sign out URLs) and make sure that the address matches the related settings in the “auth.js” file exactly. For Allowed OAuth Flows, select implicit grant. For Allowed OAuth Scopes, select openid.

The app integration configuration is now done. Your “auth.js” file should look like the following:

The preceding resources don’t exist anymore. The CloudFormation stack that generated them was deleted. I recommend that you delete your stack after testing, for cleanup purposes. Deleting the stack also deletes all the resources.

Next, upload the four JS and HTML files to the S3 bucket named “cognitoquicksight-s3website-xxxxxxxxx”. Make sure that all files are publicly readable:

Congratulations, the configuration part is now finished!

It’s time to create your first user. Access your CloudFront distribution address in a browser and choose SIGN IN / SIGN UP.

On the Amazon Cognito hosted UI, choose SIGN UP and provide a user name, password and a valid email.

You receive a verification code in email to confirm the user.

In a production system, you might not want to allow open access to your dashboards. As you now have a confirmed user, you can disable the sign-up functionality altogether to avoid letting other users sign themselves up.

In the Amazon Cognito User Pools console, choose General settings, Policies and select Only allow administrators to create users.

In the web app, you can now sign in as the Amazon Cognito user to access the Amazon QuickSight console. Because this is the first time this user is accessing Amazon QuickSight with an IAM role, provide your email address and sign up as an Amazon QuickSight user.

Enjoy your federated access to Amazon QuickSight!

After you’re done testing, go to the CloudFormation console and delete the CognitoQuickSight stack to remove all the resources.

Extending and customizing the solution

Additionally, you could configure SAML federation for your user pool with a couple of clicks, following the instructions in the Amazon Cognito User Pools supports federation with SAML post. If you add more than one SAML IdP, Amazon Cognito can identify the provider to which to redirect the authentication request, based on the user’s corporate email address.

It’s important to understand that while Amazon Cognito User Pools is authenticating (AuthN) the user, the IAM role created for the identity pool is authorizing (AuthZ) the user to perform actions on specific resources. As it is configured, the role only allows “quickSight:CreateUser” permissions. For additional permissions, modify the role accordingly, as in Setting Your IAM Policy. If your users create datasets, remember to add access to data sources such as Amazon S3.

You can customize this solution further by adding multiple groups to your user pool and associating each group with different IAM roles. For more information, see Amazon Cognito Groups and Fine-Grained Role-Based Access Control. For instance, with role-based access control, it’s possible to have a group for Amazon QuickSight administrators and one for users.

You can also modify the sign-In URL (Step 6) to redirect your user to any other service console, provided that the IAM role has appropriate permissions. After receiving a valid sign-in token from the SSO federation endpoint, the user is redirected to https://quicksight.aws.amazon.com. However, you can change the redirection to the main AWS console at https://console.aws.amazon.com. You could also change it to specific services, such as Amazon Redshift, Amazon EMR, Amazon Elasticsearch Service and Kibana (In this particular case the application needs to return an AWS Signature Version 4 – Sigv4 – signed URL based on the temporary credentials received from Cognito instead of calling the AWS Sign-In Federation endpoint), Amazon Kinesis, or AWS Lambda. Or, you can even customize a frontend portal with separate links to multiple specific services and resources that the user is only allowed to access provided that the IAM role being assumed has access to those services and resources.

Conclusion

With the power, flexibility, security, scalability, and the new federation and application integration features of Amazon Cognito user pools, there’s no need to worry about the undifferentiated heavy lifting of maintaining your own identity servers. This allows you to focus on application logic and secure access to other great AWS services, such as Amazon QuickSight.

If you have questions or suggestions, please comment below.


About the Author

Ed Lima is a Solutions Architect who helps AWS customers with their journey in the cloud. He has provided thought leadership to define and drive strategic direction for adoption of Amazon platforms and technologies, skillfully adapting and blending business requirements with technical aspects to achieve the best outcome helping implement well architected solutions. In his spare time, he enjoys snowboarding.