Using AWS Cognito and AD FS as authentication for a web app
Asked Answered
B

1

14

We are currently building a web app using a full serverless stack on AWS. So far we have been very successful using AWS Lambda, AWS DynamoDB and Cognito User Pools. This application is intended to be an enterprise application and one of my clients wants to be able to log all users in using their current Active Directory credentials. I have used AD FS in the past on other applications but it has always turned out to be a bit of a hack to get it working.

Now, I want to send the customer instructions on how to configure their AD FS relying party trust to authenticate against my application.

I have read that the best way to do this is to create a Cognito Identity Provider that links to a Cognito User Pool. In the User Pool you should create a SAML provider and upload the metadata.xml from the AD FS server.

I have set up a lab server with AD FS and I can get that working. Now I am not sure what I am doing wrong in terms of the Relying Party Trust setup or the Cognito setup. I have been at this for ages and read just about every blog article I can find. If anyone can help me out or point me in the right direction that would be greatly appreciated.

Bluing answered 13/5, 2018 at 12:10 Comment(5)
Are you getting an ADFS error or a Cognito error?Hammurabi
@nzpcmad I managed to sort it out but to answer your question, I was actually getting different errors at different times.Bluing
Was your AD FS server running in AWS also? Or in a corporate network? If the latter, how did you securely connect to it?Atrophied
The test one was running on AWS. For my clients, they have their servers running on site in their corporate network. They have all the security certificates handled. Unfortunately that's not my area of expertise but it was all secured and handled correctly.Bluing
Related: https://mcmap.net/q/829098/-how-to-proceed-with-ad-fs-saml-for-aws-cognito/843660Occupier
B
24

After much frustration, I can now answer this question so I decided to put together an easy step-by-step answer for beginners with these struggles.

I am only going into the authentication setup and not the authorisation. Authorisation requires IAM roles and some other logic that is architecture specific. I'm happy to discuss that elsewhere.

There are 2 components to this kind of a setup:

  1. An AWS Cognito user pool with a federated identity provider
  2. Windows Server with AD FS installed

Creating the Cognito User Pool domain

In the Cognito User Pool under General Settings, select App clients and add one if there are none (you will need the ID later).

Then go to Domain Name under App Integration and choose a valid domain prefix and save it.

Relying Party Trust in Windows AD FS

You will need to get the company to setup a relying party trust. The steps required are as follows:

  1. Open the AD FS management console
  2. Create a new relying party trust
  3. Select to enter the details manually
  4. Enter a name for the trust that is easily identifiable as your application
  5. Select to use ADFS 2.0
  6. In this example, there is no need for a certificate so just click next
  7. Select the checkbox to enable the SAML 2.0 protocol and enter the URL in this format: https://<domain_prefix>.auth.<region>.amazoncognito.com/saml2/idpresponse (domain prefix is set in the previous step)
  8. The relying party trust identifier needs to be urn:amazon:cognito:sp:<pool-id> where pool-id is the AWS Cognito User Pool id found in the General Settings of the user pool
  9. Permit all users to authenticate (assuming that is your intention)

Now you need to add claims to the relying party trust.

  1. Right-click on the relying party trust and click edit claims
  2. Create a new claim that sends LDAP attributes
  3. Give it a name (I normally use Profile but this is up to you)
  4. Make the attribute store Active Directory
  5. Fill in the table as you need. A requirement is that you have a Name ID being returned (I normally use the User-Principal-Name mapping to Name ID). The rest of the table is as you need. For example, Given-Name can map to FName

Federated Identities in AWS Cognito User pool

So as the application developer, you need to setup the Cognito User pool. Go through the wizard and choose your prefered settings. The federated identities don't necessarily play by the same rules as the user pool itself anyway.

The steps to setup the federated identity are:

  1. In the Cognito user pool select Identity Providers under Federation
  2. Click on SAML
  3. Provide the metadata document endpoint (normally in the form of https://<fqdn>/FederationMetadata/2007-06/FederationMetadata.xml). If you can't then download that file and upload it by clicking "Select File"
  4. Enter a provider name that makes sense to you but make sure not to put any spaces in the name
  5. The identifiers are optional (see below for their use)
  6. Checking enable IdP sign out flow will sign your users out of their federated identity as well as your application on sign out.
  7. Click create provider

Attribute Mapping for Federated Identity

  1. Create the field mappings for the Federated Identity by going to Attribute Mapping under Federation in the user pool.
  2. Select SAML
  3. Click Add SAML Attribute
  4. Make sure Capture is checked, enter the SAML attrbites from above (such as FName) and select the user pool attribute that it maps to.

Setting up the App Client

The last step before testing is to setup the app client that you created earlier.

  1. Go to App Client Settings under App Integration
  2. Enter the settings for the appropriate app client
  3. Select all the appropriate identity providers (specifically the one setup above)
  4. You can set a comma-separated list of callback and logout URLs. The callback URLs should point to somewhere that will use the token after authentication (see testing below).
  5. Select the OAuth 2.0 attributes as required but for testing select everything but Client credentials

Testing

To test, you can try a few different URLs in the form of: -

  • https://<domain_prefix>.auth.<region>.amazoncognito.com/authorize?idp_identifier=<idp_identifier>&response_type=token&client_id=<app_client_id>&redirect_uri=<app_client_callback_URL> to go directly to the authorize endpoint
  • https://<domain_prefix>.auth.<region>.amazoncognito.com/login?response_type=token&client_id=<app_client_id>&redirect_uri=<app_client_callback_URL> to go to the AWS hosted login UI

The idp_identifier is the optional field defined when creating the federated identity. This is not required in the URL either.

This one page webapp is a good tool to use to test that things are working and you are getting the desired response.

I hope this helps other people.

Bluing answered 16/5, 2018 at 14:5 Comment(2)
Hi, thanks for sharing, any chance you could provide a screen shot of the ADFS side? Struggling to get this working. I can't believe how long I've been fighting this. Was a slam dunk on integrating with the console as AWS had a great blog article on it. Not so much on the Cognito User Pools. Thanks!Crabwise
Same problem my side. Do you know which part you need a screenshot of particularly? What is not working your side?Bluing

© 2022 - 2024 — McMap. All rights reserved.