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.
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:
- An AWS Cognito user pool with a federated identity provider
- 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:
- Open the AD FS management console
- Create a new relying party trust
- Select to enter the details manually
- Enter a name for the trust that is easily identifiable as your application
- Select to use ADFS 2.0
- In this example, there is no need for a certificate so just click next
- 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)
- 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
- Permit all users to authenticate (assuming that is your intention)
Now you need to add claims to the relying party trust.
- Right-click on the relying party trust and click edit claims
- Create a new claim that sends LDAP attributes
- Give it a name (I normally use Profile but this is up to you)
- Make the attribute store Active Directory
- 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:
- In the Cognito user pool select Identity Providers under Federation
- Click on SAML
- 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"
- Enter a provider name that makes sense to you but make sure not to put any spaces in the name
- The identifiers are optional (see below for their use)
- Checking enable IdP sign out flow will sign your users out of their federated identity as well as your application on sign out.
- Click create provider
Attribute Mapping for Federated Identity
- Create the field mappings for the Federated Identity by going to Attribute Mapping under Federation in the user pool.
- Select SAML
- Click Add SAML Attribute
- 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.
- Go to App Client Settings under App Integration
- Enter the settings for the appropriate app client
- Select all the appropriate identity providers (specifically the one setup above)
- 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).
- 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.