Implementing SSO Login for SAML Providers Using AWS Cognito

Introduction

In modern enterprises, Single Sign-On (SSO) is an essential authentication mechanism that enhances security and streamlines user access across multiple services. SSO prevents password-related attacks, ensures centralized access control, and maintains detailed access logs. Organizations use SSO solutions from providers such as Microsoft Entra ID, Okta and public identity providers like Google and Facebook to simplify authentication.

Instead of manually handling attribute mapping and direct integration with an Identity Provider (IdP), leveraging AWS Cognito to enable SSO authentication is a better approach which allows for an easier integration while benefiting from Cognito’s built-in user management capabilities.

Why AWS Cognito for SSO with SAML?

When researching options, for SSO with SAML AWS Amplify Gen 2 supports SAML directly. However, since the project was currently using Amplify Gen 1, switching to Gen 2 was not feasible due to its reliance on AWS CDK and the need for direct hosting.

This limitation required manipulating Cognito’s SDK and API endpoints to integrate with a SAML IdP. Cognito offers two primary login methods:

  1. Hosted UI: AWS provides a fully hosted authentication UI with preconfigured options for sign-up and sign-in which is the legacy solution.
  2. Managed Login: A customizable, ready-to-use UI for authentication operations like sign-in, sign-out, and password management.

With this understanding, let’s dive into the implementation details.

Step 1: Create a Cognito User Pool

You can create a Cognito User Pool using:

  1. AWS Console
  2. AWS CLI (create-user-pool command)
  3. AWS SDK (cognito-identity-provider package)

Refer to the AWS Cognito documentation for the exact steps in your preferred method.

Step 2: Configure a Cognito App Client

After creating the user pool, we need to create an App Client. This client manages authentication requests and should have an App Client ID and an App Client Secret for improved security.

Configure the callback URL and logout URL under the App Client’s Login Page tab.

Ensure that the response type is set to code or Authorization Code grant Flow for security reasons.

Step 3: Understanding OAuth Parameters

When using Cognito’s login URL it includes a domain and the region:

https://{domain}.auth.{region}.amazoncognito.com/login

It also includes query parameters:

  1. client_id: Unique identifier for the App Client.
  2. response_type: Always set to code to follow the authorization code grant approach.
  3. scopes: Define user access permissions (e.g., email, openid, profile, and aws.cognito.signin.admin).
  4. redirect_uri: Specifies where the authentication response is sent.

In multi-tenant SaaS applications we can have app client based isolation for each tenants in the application.

For more details, refer to AWS Cognito OAuth Grants and for app client based isolation AWS App-client multi-tenancy

Step 4: Configuring Okta as the Identity Provider (IdP)

For this implementation, I used Okta as the external SAML Identity Provider.

Steps to Configure Okta:

  1. Sign up for an Okta Developer Account (free version available).

  2. Create Users and Groups under the People tab.

  3. Create a new Application and enter the necessary details.

  4. Use the Cognito Assertion Consumer Service (ACS) URL:

https://{domain}.auth.{region}.amazoncognito.com/saml2/idpresponse

  1. Set the Audience URI / SP Entity ID:

urn:amazon:cognito:sp:{userpool_id}

  1. Configure attribute mappings, ensuring the email field in Okta (user.email) is mapped to Cognito’s email attribute.

  2. Sign authentication requests using a certificate from Cognito and upload it to Okta.

For further configuration details, refer to the Integrating 3rd party SAML providers.

Step 5: Configuring Logout Endpoint

To ensure that users are fully logged out from both Cognito and Okta, configure the logout URL:

https://{mydomain}.auth.{region}.amazoncognito.com/saml2/logout

Refer to the Managed Logout Endpoint for details on how sessions are terminated.

Step 6: Handling Signing Certificates

  1. The signing certificate from Cognito must be uploaded to Okta.
  2. The validity period for Cognito’s signing certificate is 10 years.
  3. The metadata URL from Okta should be used to configure Cognito’s Social and External Providers settings.
  4. The signing certificate is available in .crt format and can be downloaded from Cognito’s Social and External Providers settings.

Step 7: Configuration of Social and External providers in the Cognito

  1. Add the metadata url received from Okta.
  2. Map the correct user attributes from Okta to Cognito.

That’s it we have implemented a multi-tenant based SSO Login for SAML providers with user management of the application offloaded to Cognito.

Conclusion

We have successfully configured AWS Cognito as a SAML-based SSO solution with Okta as the Identity Provider. This approach offloads user management responsibilities to Okta while allowing Cognito to handle authentication workflows efficiently.

By leveraging Cognito’s App Client-based multi-tenancy approach, we can isolate different entities while still managing authentication through a centralized service. Additionally, we now have a secure login and logout flow that ensures compliance with OAuth 2.0 best practices.

If you have any questions, feel free to ask in the comments section!

References:

  1. Amplify Gen 2
  2. AWS Cognito OAuth Grants
  3. Integrating 3rd party SAML providers
  4. Managed Logout Endpoint
  5. Project URL:
    You can find the project details and source code in the Backend Repository Azure DevOps Services | Sign In
3 Likes