Introduction
UPDATE 04-2018: Updated the blog to be more up to date with current amazon configuration, also the default configuration is now multiple account support.
Jeff Wierer has written this documentation in Oktober 2014. This is a 2015 update containing windows server 2012R2 and ADFS 3.x
AWS added support for SAML, an open standard used by many identity providers. This new feature enables federated single sign-on (SSO), which lets users sign into the AWS Management Console or make programmatic calls to AWS APIs by using assertions from a SAML-compliant identity provider (IdP) like ADFS.
Many of you are using Windows AD for your corporate directory and since Windows Server includes ADFS, it makes sense that you might use ADFS as your IdP.
To set up my domain, I used Amazon EC2 because that made it easy to access the domain from anywhere.
My EC2 instance used Windows Server 2012 R2 running, AD, and ADFS. (Remember that the IIS dependency was removed in ADFS 2012 R2.)
If you want to do the same, I encourage you to use a nifty CloudFormation template that creates a Windows instance and sets up a domain for you.
How Integration Between AD FS and AWS Works
Before we get too far into the configuration details, let’s walk through how this all works.
- The flow is initiated when a user (let’s call him Bob) browses to the ADFS sample site inside his domain. When you install ADFS, you get a new virtual directory named adfs for your default website, which includes this page
- The sign-on page authenticates Bob against AD. Depending on the browser Bob is using, he might be prompted for his AD username and password.
- Bob’s browser receives a SAML assertion in the form of an authentication response from ADFS.
- Bob’s browser posts the SAML assertion to the AWS sign-in endpoint for SAML (https://signin.aws.amazon.com/saml). Behind the scenes, sign-in uses the AssumeRoleWithSAML API to request temporary security credentials and then constructs a sign-in URL for the AWS Management Console.
- Bob’s browser receives the sign-in URL and is redirected to the console.
From Bob’s perspective, the process happens transparently. He starts at an internal web site and ends up at the AWS Management Console, without ever having to supply any AWS credentials.
Now that we understand how it works, let’s take a look at setting it all up.
BTW this post is fairly long. The next couple sections cover installing and configuring ADFS.
If you already have ADFS in your environment, you may want to skip ahead to the Configuring AWS section.
Configuring Active Directory
If you want follow along with my description, you’re going to need a Windows domain.
If you don’t already have one, I recommend that you take advantage of the CloudFormation template I mentioned earlier to quickly launch an Amazon EC2 Windows instance as a Windows AD domain controller.
For demonstration purposes, I used a single user (Bob) who is a member of two AD groups (AWS-awsaccountid-AWS-PROD-ADMIN and AWS-awsaccountid-AWS-PROD-DEV, replace awsaccountid with your actual account id, for example : AWS-123456789-AWS-PROD-ADMIN) and a service account (ADFSSVC) used by ADFS. Note that the names of the AD groups both start with AWS-. This is significant, because Bob’s permission to sign in to AWS will be based on a match of group names that start with AWS-, as I’ll explain later.
If you follow along with the instructions, make sure you use exactly the same names we do for users, AD groups, and IAM roles, including uppercase and lowercase letters.
Perform the following in your domain:
- Create two AD Groups named AWS-awsaccountid-AWS-PROD-ADMIN and AWS-awsaccountid-AWS-PROD-DEV ( replace awsaccountid with your actual account id, for example : AWS-123456789-AWS-PROD-ADMIN)
- Give Bob an email address (e.g., bob@example.com)
- Add Bob to the AWS-awsaccountid-AWS-PROD-ADMIN and AWS-awsaccountid-AWS-PROD-DEV groups
- Create another user named ADFSSVC. This account will be used as the ADFS service account later on.
Installing ADFS
With my accounts and groups set up, I moved on to installing ADFS. On the Windows Server 2012 R2 i’m using we can install adfs 3.0 out of the box so i used this one. Open up the server manager and use the “install roles and features”.
Select the ADFS role
Confirm the changes you are going to make and install ADFS, no reboot is needed
Configuring ADFS
The next step is to configure ADFS.
Launch the console by → Start > All Programs > Administration Tools > AD FS Management
To launch the configuration wizard, select AD FS Federation Server Configuration Wizard
If you want to follow along with my configuration, do this:
1. Select Create a new Federation Server in a server farm
2. Select a domain admin account, i used the default administrator in this demo.
3. Select a SSL certificate. On my instance, I had an existing certificate I could use. If you don’t have a certificate, you can create a self-signed certificate using IIS. Self-signed certificates are convenient for testing and development. For production use, you’ll want to use a certificate from a trusted certificate authority (CA).
4. Remember the service account I mentioned earlier? This is where you use it.
5. Select the internal database, or a sql server if you have one available
6. Review the options and then check the prereqs, click configure to begin the installation
7. When it’s done, the following will appear:
If so, skip ahead to the Configuring AWS section.
During my testing, I went through this wizard on several different Windows servers and didn’t always have 100% success. In some cases I encountered the following error message:
It turns out this is a known issue that can be fixed by running the following at the command line (Make sure you run the command window as an administrator):
setspn -a host/localhost adfssvc
Note that is the name of the service account I used.
If the command is successful, you see output like this:
Registering ServicePrincipalNames for CN=ADFSSVC,CN=Users,DC=mydomain,DC=aws,DC=amazon,DC=com host/localhost
Configuring AWS
You’ve finished configuring AD FS. The next step is to configure the AWS end of things.
To do this, I used the AWS Management Console
The first step is to create a SAML provider.If you’ve never done this, I recommend taking a look at the IAM user guide.
Before you create a SAML provider, you need to download the SAML metadata document for your ADFS federation server. By default, you can download it from following address:
https://localhost/FederationMetadata/2007-06/FederationMetadata.xml
You can also use the following powershell script :
$source = "https://localhost/FederationMetadata/2007-06/FederationMetadata.xml"
$destination = "C:\Users\Administrator\Documents\FederationMetadata.xml"
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
Invoke-WebRequest $source -OutFile $destination
I named my SAML provider Federation-Demo. When you have the SAML metadata document, you can create the SAML provider in AWS. As part of that process, you upload the metadata document.
When I finished creating the SAML provider, I created two IAM roles. Once again the IAM documentation has a great walkthrough of these steps, so I won’t repeat them here.
I created two roles using the Grant Web Single Sign-On (WebSSO) access to SAML providers role wizard template and specified the ADFS SAML provider that I just created.
I named the two roles AWS-PROD-ADMIN and AWS-PROD-DEV. Do these names look familiar? They should.
They are the complement to the AD groups created earlier. During the SAML authentication process in AWS, these IAM roles will be matched by name to the AD groups (AWS-awsaccountid-AWS-PROD-ADMIN and AWS-awsaccountid-AWS-PROD-DEV) via ADFS claim rules.
Note: Remember that if you’re following along with this description, you need to use exactly the same names that we use. Make sure that you name the IAM roles AWS-PROD-ADMIN and AWS-PROD-DEV.
Find the ARNs for the SAML provider and for the roles that you created and record them. You’ll need the ARNs later when you configure claims in the IdP.
That’s it for the AWS configuration steps.
Configuring AWS as a Trusted Relying Party
Federation using SAML requires setting up two-way trust.
In the preceding section I created a SAML provider and some IAM roles. This is one half of the trust relationship, where the ADFS server is trusted as an identity provider.
Similarly, ADFS has to be configured to trust AWS as a relying party. I configured this by returning to the AD FS Management Console. To recreate my setup, perform the following:
1. From the ADFS Management Console, right-click ADFS and select Add Relying Party Trust.
2. In the Add Relying Party Trust Wizard, click Start.
3. Check Import data about the relying party published online or on a local network, enter https://signin.aws.amazon.com/static/saml-metadata.xml, and then click Next. The metadata XML file is a standard SAML metadata document that describes AWS as a relying party.
4. Set the display name for the relying party and then click Next.
5. We will ignore the MFA settings for now
6. Choose your authorization rules. For my scenario, I chose Permit all users to access this relying party. When you’re done, click Next.
7. Review your settings and then click Next.
You’re done configuring AWS as a relying party.
Configuring Claim Rules for the AWS Relying Party
In these steps we’re going to add the claim rules so that the elements AWS requires and ADFS doesn’t provide by default (NameId, RoleSessionName, and Roles) are added to the SAML authentication response.
Right-click on the relying party (in this case Amazon Web Services) and then click Edit Claim Rules.
Here are the steps I used to create the claim rules for NameId, RoleSessionName, and Roles.
Adding NameId
1. In the Edit Claim Rules for <relying party> dialog box, click Add Rule.
2. Select Transform an Incoming Claim and then click Next.
3. Use the following settings:
a. Claim rule name: NameId
b. Incoming claim type: Windows Account Name
c. Outgoing claim type: Name ID
d. Outgoing name ID format: Persistent Identifier
e. Pass through all claim values:checked
4. ClickFinish.
Adding a RoleSessionName
1. Click Add Rule
2. In the Claim rule template list, select Send LDAP Attributes as Claims.
3. Use the following settings:
Claim rule name: RoleSessionName
Attribute store: Active Directory
LDAP Attribute: E-Mail-Addresses
Outgoing Claim Type: https://aws.amazon.com/SAML/Attributes/RoleSessionName
4. Click Finish
Adding Role Attributes
1. Click Add Rule.
2. In the Claim rule template list, select Send Claims Using a Custom Rule and then click Next.
3. For Claim Rule Name, select Get AD Groups, and then in Custom rule, enter the following:
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
=> add(store = "Active Directory", types = ("http://temp/variable"), query = ";tokenGroups;{0}", param = c.Value);
I use this in the next rule to transform the groups into IAM role ARNs.
4. Click OK.
5. Click Add Rule.
This custom rule uses a script in the claim rule language that retrieves all the groups the authenticated user is a member of and places them into a temporary claim named http://temp/variable. (Think of this as a variable you can access later.)
6. Repeat the preceding steps, but this time enter Roles for Claim rule name and use the following script:
c:[Type == "http://temp/variable", Value =~ "(?i)^AWS-([\d]{12})"] => issue(Type = "https://aws.amazon.com/SAML/Attributes/Role", Value = RegExReplace(c.Value, "AWS-([\d]{12})-", "arn:aws:iam::$1:saml-provider/idp1,arn:aws:iam::$1:role/"));
7. Click OK.
Adjusting Session Duration
1. Click Add Rule.
2. In the Claim rule template list, select Send Claims Using a Custom Rule and then click Next.
3. For Claim Rule Name, select Session Duration and then in Custom rule, enter the following:
=> issue(Type = "https://aws.amazon.com/SAML/Attributes/SessionDuration", Value = "28800");
(Adjust the value of 28800 seconds (8 hours) as appropriate.)
Testing the configuration
1. In your adfs server, browse to the following address: https://localhost/adfs/ls/IdpInitiatedSignOn.aspx
If you’re using a locally signed certificate from IIS, you might get a certificate warning.
On any other server/client, you need to replace localhost with the actual hostname of your adfs server.
2. Select Sign in to one of the following sites, select Amazon Web Services from the list, and then click Continue to Sign In.
3. If prompted, enter in a username and password (remember to use Bob’s account).
You will be redirected to the Amazon Web Services Sign-In page.
4. Select a role and then click Sign In. (If you are mapped to only a single IAM role, you skip the role selection step and are automatically signed into the AWS Management Console.)
ADDENDUM
To give yourself a faster working demo download the below zip file.
Give the cf-demo-ad-adfs.yaml to cloudformation.
It will create a 2012r2 server with a domain installed.
You can then login to the server(copy contents of zip file) and install the aws cli, and run the adfs.ps1 powershell script.
Steps the script will do:
- Prompt you for your aws account id
- Install adfs feature
- Add adfs service account
- Create self-signed certificate
- Counter adfs installation bug
- Install adfs farm
- Add Relying Party Trust
- Create 2 active directory groups
- Create test user bob -> will ask for his password
- Set emails for the domain
- Disable IE security (else much popups)
- Create saml provider
- Create iam role’s
Have fun!
Read Jeff Wierer’s original article here: http://blogs.aws.amazon.com/security/post/Tx71TWXXJ3UI14/Enabling-Federation-to-AWS-Using-Windows-Active-Directory-ADFS-and-SAML-2-0
eijer
Hello,
Thank for informative article!
I would like to configure AWS Cognito to receive the user’s department name and user’s full name from ADFS. At this time, I would like to get help if you have experience in how to construct the Claims rule.