Integrating Okta as a SAML identity provider in an Amazon Cognito user pool

Amazon Cognito user pool allows users to sign-in through an external identity provider (federation), such as Okta. A user pool integrated with Okta allows users in your Okta app to get user pool tokens from Amazon Cognito and authenticate apps that use cognito.

Prerequisites
1. Cognito user pool created in the aws account 
2. Okta developer account

Steps
1. Create an app client in your user pool

a. When adding an app client, clear the Generate client secret check box. 
b. Select the required auth flows 
     Select at least ALLOW_USER_SRP_AUTH and ALLOW_REFRESH_TOKEN_AUTH

Note:We are using “Authorization code grant” authentication flow which does not require client secrets.

2. Create your cognito user pool domain

a. Under App Integration tab in user pool console side menu, choose Domain name
b. Enter your choice of unique domain prefix which is used to build cognito login url for your SAML app.

3. Create a SAML app in Okta

a. Sign in to okta with admin access credentials and click on “Admin” button on top right corner
b. On the admin menu choose Applications, and then choose Add Application.
c. On the Add Application page, choose Create New App.
d. In the Create a New Application Integration dialog, confirm that Platform is set to Web.
e. For Sign on method, choose SAML 2.0.
 f. Choose Create, this will open a General Settings page for saml app.

(i) Enter a name for your app.
(ii) (Optional) Upload a logo and choose the visibility settings for your app.
(iii) Choose Next.

(iv) Under GENERAL, for Single sign on URL, enter https://yourDomainPrefix.auth.region.amazoncognito.com/saml2/idpresponse.

Note: Replace yourDomainPrefix and region with the values for your user pool. Find these values in the Amazon Cognito console on the Domain name page for your user pool.

 (v) For Audience URI (SP Entity ID), enter urn:amazon:cognito:sp:yourUserPoolId.

Note: Replace yourUserPoolId with your Amazon Cognito user pool ID. Find it in the Amazon Cognito console on the General settings page for your user pool.

 (vi) Under ATTRIBUTE STATEMENTS (OPTIONAL- specifies which user attributes you want to export to cognito), add a statement with the following information:

For Name, enter the SAML attribute name (attribute name by which you want to user attributes to be passed to cognito in SAML response).

eg: if you want to pass user email in SAML response and you want to call it ‘Email Id’ enter ‘Email id’ in Name field and enter ‘user.email’ in Value field.

(vii) For all other settings on the page, leave them as their default values or set them according to your preferences.
(viii) Choose Next.
(ix) Choose a feedback response for Okta Support.
(x) Choose Finish.

4. Assign an user to your Okta application

a. On the Assignments tab for your Okta app, for Assign, choose Assign to People.
b. Next to the user that you want to assign, choose Assign.

Note: If this is a new account, the only option available is to choose yourself (the admin) as the user.

c. (Optional) For User Name, enter a user name, or leave it as the user’s email address, if you want.
d. Choose Save and Go Back. Your user is assigned.
e. Choose Done.

5. Get the IdP metadata for your Okta application

a. On Okta developer console, navigate to Applications tab and select your application.
b. On the Sign On tab, find the Identity Provider metadata hyperlink (Look for text ‘Identity Provider metadata is available if this application supports dynamic configuration.’). Right-click the hyperlink (Identity Provider metadata), and then copy the URL.

6. Configure Okta as a SAML IdP in your user pool

a. In the Amazon Cognito console, choose Manage user pools, and then choose your user pool.
b. In the left navigation pane, under Federation, choose Identity providers.
c. Choose SAML.
d. Under the Metadata document, paste the Identity Provider metadata URL that you copied.
e. For Provider name, enter Okta.
f. (Optional) Enter any SAML identifiers (Identifiers (Optional)) and enable sign-out from the IdP (Okta) when your users sign out from your user pool (Enable IdP sign out flow).
g. Choose Create provider.

7. Map SAML attributes to user pool attributes

a. In the Amazon Cognito console, choose Manage user pools, and then choose your user pool.
b. In the left navigation pane, under Federation, choose Attribute mapping.
c. On the attribute mapping page, choose the SAML tab.
d. Choose Add SAML attribute.
e. For SAML attribute, enter the SAML attribute name (attribute name which you have mentioned in ATTRIBUTE STATEMENTS while creating SAML app in Okta.

eg: we had specified ‘Email Id’ in the example above so mention ‘Email Id’ under SAML attribute and select Email under User pool attribute, continue and map all other attributes if you had mentioned any other in ATTRIBUTE STATEMENTS and Choose Save changes.

Note:Make sure all mapped attributes in cognito are readable and writable, you can set attribute permissions in General settings->App clients->Set read and write permissions.

8. Change app client settings for your user pool

a. In the Amazon Cognito console, choose Manage user pools, and then choose your user pool.
b. In the left navigation pane, under App integration, choose App client settings.
c. On the app client page, do the following:
Under Enabled Identity Providers, select the Okta and Cognito User Pool check boxes.
For Callback URL(s), enter a URL where you want your users to be redirected after they log in. For testing, you can enter any valid URL, such as https://www.example.com/.
For Sign out URL(s), enter a URL where you want your users to be redirected after they log out. For testing, you can enter any valid URL, such as https://www.example.com/.
Under Allowed OAuth Flows, be sure to select Authorization code grant check box.
Under Allowed OAuth Scopes, be sure to select  the email and profile check boxes.
d. Choose Save changes.

9. Construct the endpoint URL

a. Using values from your user pool, construct this login endpoint URL:
https://yourDomainPrefix.auth.region.amazoncognito.com/login?response_type=code&client_id=yourClientId&redirect_uri=redirectUrl
b. Be sure to do the following:

(i) Replace yourDomainPrefix and region with the values for your user pool. Find these values in the Amazon Cognito console on the Domain name page for your user pool.
(ii) Replace yourClientId with your app client’s ID, and replace redirectUrl with your app client’s callback URL. Find these in the Amazon Cognito console on the App client settings page for your user pool.

10. Test the endpoint URL

a. Enter the constructed login endpoint URL in your web browser.
b. On your login endpoint webpage, choose Okta.

Note: If you’re redirected to your app client’s callback URL, you’re already logged in to your Okta account in your browser. The user pool tokens appear in the URL in your web browser’s address bar.

c. On the Okta Sign In page, enter the username and password for the user that you assigned to your app.

d. Choose Sign in.

After logging in, you’re redirected to your app client’s callback URL. The authorization code appears in the URL in your web browser’s address bar.

11. Complete authentication by getting tokens from cognito

a. Your application can then extract the authorization code from the query parameters and exchange it for user pool tokens. The exchange occurs by submitting a POST request to
https://yourDomainPrefix.auth.region.amazoncognito.com/oauth2/token with the following parameters:

(i) grant_type – Set to “authorization_code” for this grant.
(ii) code – The authorization code that’s vended to the user.
(iii) client_id – yourClientId.
(iv) redirect_uri – redirectUrl.

b. The JSON returned in the resulting response has the following keys:

(i) id_token – A valid user pool ID token. Note that an ID token is only provided if the openid scope was requested.
(ii) access_token – A valid user pool access token.
(iii) refresh_token – A valid user pool refresh token. This can be used to retrieve new tokens by sending it through a POST request to
https://yourDomainPrefix.auth.region.amazoncognito.com/oauth2/token, specifying the refresh_token and client_idparameters, and setting the grant_type parameter to “refresh_token“.
(iv) expires_in – The length of time (in seconds) that the provided ID and/or access token(s) are valid for.
(v) token_type – Set to “Bearer“.