Integrating Azure AD and AWS – Part 4

Integrating Azure AD and AWS – Part 4

We’ve reached the end of the road for my series on integrating Azure Active Directory (Azure AD) and Amazon Web Services (AWS) for single sign-on and role management. In part 1 I walked through the many reasons the integration is worth looking at if your organization is consuming both clouds. In part 2 I described the lab I used to for this series, described the different way application identities (service accounts for those of you in the Microsoft space) are handled in Active Directory Domain Services versus Azure AD, and walked through what a typical application identity looks like in Azure AD. In part 3 I walked through a portion of the configuration steps, did a deep dive into the Azure AD and AWS federation metadata, examined a SAML assertion, and configured the AWS end of the federated trust through the AWS Management Console. This included creation of an identity provider representing the Azure AD tenant and creation of a new IAM role for users within the Azure AD tenant to assert.

In this final post I’ll cover the remainder of the configuration, describe the “provisioning” capabilities of Azure AD in this integration, and pointing out some of the issues with the recommended steps in the Microsoft tutorial.

Before I continue with the configuration, let me cover what I’ve done so far.

  • Part 2
    • Added the AWS application from the Azure AD Application Gallery through the Azure Portal.
  • Part 3
    • Assigned an Azure Active Directory user to the application through the Azure Portal.
    • Configured the Azure AD to pass the Role and RoleSessionName claims through the Azure Portal.
    • Created the SAML identity provider representing Azure AD in the AWS Management Console.
    • Created an AWS IAM Role and associated it with the identity provider representing Azure AD in the AWS Management Console.

At this point JoG users can assert their identity to their heart’s content but we don’t have a list of what AWS IAM roles stored in Azure AD for our users to assert.  So how do we assert a role from Azure AD if the listing of the roles exists in AWS?  The wonderful concept of application programmatic interfaces (APIs) swoops in and saves the day.  Don’t get me wrong, if you hate yourself you can certainly provision them manually by modifying the application manifest file every time a new role is created or deleted.  However, there is an easier route of having Azure AD pick up those roles directly from AWS on an automated schedule.  How does this work?  Well nothing works better than demonstrating how the roles can be queried from the AWS API.

The AWS SDK for .NET makes querying the API incredibly easy.  We’re not stuck worrying about assembling the request and signing it.  As you can see below the script is six lines of code in PowerShell.

Script.png

The result is a listing of the roles configured in AWS which includes the AzureADEC2Admins role I created earlier.  This example demonstrates the power a robust API brings to the table when integrating cloud services.

2

When Microsoft speaks of provisioning in regards to the AWS integration, they are talking about provisioning the roles defined in AWS to the the application manifest file in Azure AD.  This provides us with the ability to assign the roles from within the Azure Portal as we’ll see later.  This differs from many of the Azure AD integrations I’ve observed in the past where it will provision a record for the user into the software as a service (SaaS) offering.  Below is a simple diagram of the provisioning process.3

To do support provisioning we need to navigate to the AWS Management Console, open the Services Menu, and select IAM.  We then select Users and hit the Add User button.  I named the user AzureAD, gave it programmatic access type, and attached the IAMReadOnlyAccess policy.  AWS then presented me with the access key ID and secret access key I’ll need to provide to Azure AD.  Yes, we are going to follow security best practices and provide the account with the minimum rights and permissions it needs to provide the functionality.  The Microsoft tutorial instructs you to generate the credentials under the context of the AWS administrator effectively giving the application full rights to the AWS account.  No Microsoft, just no.

I next bounce back to the Azure portal and to the AWS application configuration.  From here I select the Provisioning option, switch the drop-down box to Automatic, and plug the access key ID into the clientsecret field and the secret access key into the secret token field.  A quick test connection shows success and I then save the configuration.  Note that you must first save the configuration before you can turn on the synchronization.

4

After the screen refreshes I move down to the Settings section and turn the Provisioning Status to On and set the Scope to Sync only assigned users and groups (kind of a moot point for this, but oh well).  I then Save the configuration once again and give it about 10 minutes to pull down the roles.

I then navigate back to the Users and Groups section and edit the Rick Sanchez assignment.  Hitting the role option now shows me the AzureADEC2Admins role I configured in AWS IAM.


5.png

Let’s take another look at the service principle representing the AWS application in PowerShell.  Using the Azure AD PowerShell cmdlets I referenced in entry 2 we connect to Azure AD and run the cmdlet Get-AzureADServicePrincipal which when run shows the manifest has been updated to include the newly synchronized application role.

6

We’ve configured the SAML trust on both ends, defined the necessary attributes, setup synchronization, and assigned Rick Sanchez an IAM role. In a moment we’ll demonstrate all of the pieces coming together.

Before I wrap it up, I want to quickly mention a few issues I ran into with this integration that seemed to resolve themselves without any intervention.

  1. Up to a few nights ago I was unable to get the Provisioning piece working.  I’m not putting it past user error (this is me we’re talking about) but I tried numerous times and failed but was successful a few nights ago.  I also noticed from some recent comments in the Microsoft tutorial people complaining of similar errors.  Maybe something broke for a bit?
  2. The value of the audience attribute in the audienceRestriction section of the SAML assertion generated by Azure AD doesn’t match the identifier within the AWS federation metadata.  Azure AD inserts some garbage looking audience value by default which was causing the assertions to be rejected by AWS.  After setting the identifier to the value of urn:amazon:webservices as referenced in the AWS federation metadata the assertion was consumed without issue.  I saw similar complaints in the Microsoft tutorial so I’m fairly confident this wasn’t just my issue.The story gets a bit stranger.  I wanted to demonstrate the behavior for this series by removing the identifier I had previously added.  Oddly enough the assertion was consumed without issue by AWS.  I verified using Fiddler that the audience value was populated with that garbage entry.  Either way, I would err on the side of caution and would recommend populating the identifier with the entry referenced in the AWS metadata as seen below.7.png

The last thing I want to point out is the Microsoft tutorial states that you are required to create the users in AWS prior to asserting their identity.  This is inaccurate as AWS does not require a user record to be pre-created in AWS.  This is different from a majority (if not all) of the SaaS integrations I’ve done in the past so this surprised me as well.  Either way, it’s not required which is a nice benefit if you’ve ever had to deal with the challenging of managing the identify lifecycle across cloud offerings.

Let’s wrap up this series by having Rick Sanchez log into the AWS Management Console and shutdown an EC2 instance.  Here I have logged into the Windows 10 machine named CLIENT running in Azure.  We navigate to https://myapps.microsoft.com and log into Azure AD as Rick Sanchez.  We then hit the Amazon Web Services icon and are seamless logged into the AWS Management Console.

8.png

Examining the assertion in Fiddler shows  the Role and RoleSessionName claims in the assertion.

9.png

Navigating to the EC2 Dashboard displays the instance I prepared earlier using my primary account.  Rick has full rights over administration of the instance for activities such as starting and starting the instance.  After successfully terminating the instance I log into the AWS Management Console as my primary AWS account and go to CloudTrail and see the log entries recording the activities of Rick Sanchez.

10.png

With that let’s cover some key pieces of information to draw from the series.

  1. The Azure AD and AWS integration differs from most SaaS integrations I’ve done when it comes to user provisioning.  Most of the time a user record must exist prior to the user authenticating.  There are a growing number of SaaS providers provisioning upon successful authentication as provisioning challenges grow to further consumption of cloud services, but they are still few and far between.  AWS does a solid job with eliminating the pain of pre-provisioning users.
  2. The concept of associating roles with specific identity providers is really neat on Amazon’s part.  It allows the customer to manage permissions and associate those permissions with roles in AWS, but delegate the right on a per identity provider basis to assert a specific set of roles.
  3. Microsoft’s definition of provisioning in this integration is pulling a listing of roles from AWS and making them configurable in the Azure Portal.
  4. The AWS API is solid and quite easy to leverage when using the AWS SDKs. I would like to see AWS switch from what seems to be proprietary method of application access to OAuth to become more aligned with the rest of the industry.
  5. Don’t trust vendors to make everything point and click. Take the time to understand what’s going on in the background. In a SAML integration such as this, a quick review of the metadata can save you a lot of headaches when troubleshooting issues.

I learned a ton about AWS over these past few weeks and also got some good deep dive time into Azure AD which I haven’t had time for in a while.  Hopefully you found this series valuable and learned a thing or two yourself.

In my next series I plan on writing a simple application to consume the Cognito service offered by AWS.  For those of you more familiar with the Microsoft side of the fence, it’s similar to Azure AD B2C but with some unique features Microsoft hasn’t put in place yet making a great option to solve those B2C identity woes.

Thanks and have a wonderful holiday!

Integrating Azure AD and AWS – Part 3

Welcome!  This entry continues my series in the integration of Azure AD and AWS.  In my first entry I covered what the advantages of the integration are.  In the second entry I walked through my lab configuration and went over what happens behind the scenes when an application is added to Azure AD from the application gallery.  In this post I’m going to walk through some of the configuration we need to do in both Azure AD and AWS.  I’ll also be breaking open the Azure AD and AWS metadata and examining the default assertion sent by Microsoft out of the box.

In my last entry I  added the AWS application to my Azure AD tenant from the Azure AD Application Gallery.  The application is now shown as added in the All Applications view of the Azure Active Directory blade for my tenant.

pic1.png

After selecting AWS from the listing of applications I’m presented with a variety of configuration options.  Starting with Properties we’re provided with some general information and configuration options.  We need to ensure that the application is enabled for users to sign-in and that it’s visible to users so we can select it from the access panel later on.  Notice also that that I’m configuring the application to require the user be assigned to the application.pic2

On the Users and groups page I’ve assigned Rick Sanchez to the application to allow the account access and display it on the access panel.

pic3

After waiting about 10 minutes (there is a delay in the time it takes for the application to appear in the application panel) I log into the Access Panel as Rick Sanchez and we can see that the AWS app has been added for Rick Sanchez.

pic4

Back to the properties page of the AWS application, my next stop is the Single sign-on page. Here I drop down the Single Sign-on Mode drop box and select SAML-based Sign-on option. Changing the mode to SAML-based Sign-on exposes a ton of options. The first option that caught my eye was the Amazon Web Services (AWS) Domain and URLs. Take notice of the note that says Amazon Web Services (AWS) is pre-integrated with Azure AD and requires no mandatory URL settings. Yeah, not exactly true as we progress through this series.

pic5.png

Further down we see the section that allows us to configure the unique user identifier and additional attributes.   By default Microsoft includes the name, givenName, surName, and emailAddress claims.  I’ll need to make some changes there to pass the claims Amazon requires, but let’s hold off on that for now.

pic6.png

Next up a copy of the Azure AD metadata (IdP metadata) is provided for download.  Additionally some advanced options are available which provide the capability to sign the SAML response, assertion, or both as well as switching the hash algorithm between SHA1 and SHA256.

pic7.png

Now like any nerd, I want to poke around the IdP metadata and see what the certificate Azure AD is using to sign looks like.  Opening up the metadata in a web browser parses the XML and makes the format look pretty.  From there I grab the contents X509Certificate tag (the base-64 encoded public-key certificate), dump it to Notepad, and renam it with a file extension of cer.  Low and behold, what do we see but a self-signed certificate.  This is a case where I can see the logic that the operational overhead is far greater than the potential security risk.  I mean really, does anyone want to deal with the challenge of hundreds of thousands of customers not understanding the basics of public key infrastructure and worrying about revocation, trust chains, and the like?  You get a pass Microsoft… This time anyway.

pic8.png

Before I proceed with the next step in the configuration, let’s take a look at what the assertion looks like without any of the necessary configuration.  For this I’ll use Fiddler to act as a man-in-the-middle between the client and the web.  In session 6 of the screenshot below we see that the SAML response was returned to the web browser from Azure.

pic9.png

Next up we extract that information with the Text Wizard, base-64 decode it, copy it to Notepad, save it as an XML file, and open it with IE.  The attributes containing values of interest are as follows:

  • Destination – The destination is the service provider assertion consumer URI

pic10.png

  • NameID – This is the unique identifier of the used by the service provider to identify the user accessing the service

pic11.png

  • Recipient– The recipient attribute references the service the assertion is intended for.  Oasis security best practices for SAML require the service provider to verify this attribute match the URI for the service provider assertion consumer URI

pic12.png

  • Audience – The audience attribute in the audienceRestriction section mitigates the threat of the assertion being stolen and used to impersonate a user.  Oasis security best practices require the service provider to verify this when the assertion is received to ensure it is recognizes the identifier.  The way in which this is accomplished is the value in the audience attribute is checked against the service provider EntityID attribute.

pic13.png

Additionally we have some interesting claims including tenantid, objectidentifier of the user object in Azure AD, name, surname, givenname, displayname, identityprovider, and authnmethosreferences.  I don’t think any of these need further explanation.

pic14.png

Let’s now take a look at the AWS (service provider in SAML terms) metadata.  The AWS metadata is available for download from here.  After it’s downloaded it can be opened with IE.

pic15.png

The fields of interest in this set of metadata is:

  • EntityID – The entityID is the unique identifier AWS will provide in its authentication requests.  Let’s note the value of urn:amazon:webservices for later as it will come in handy due to some issues with Microsoft’s default settings.

pic16

  • NameIDFormat – This tells me both transient and persistent are accepted.  I won’t go into details on Name ID format, you can review that for yourself in the Oasis standard.  Suffice to say the Name ID format required by the service provider can throw some wrenches into integrations when using a more basic security token service (STS) like AD FS.

pic17

  • AssertionConsumerService – This is where our browser will post back the SAML assertion after a successful authentication.  Note the URI in the location field.

pic18.png

  • RequestedAttributes – This provides us with a listing of all the attributes AWS will accept in an assertion.  Note that the only two required attributes are Role and RoleSessionName.

We’ve added the AWS application to Azure AD, granted a user access to the application, and have started the SAML setup within Azure AD (Identity Provider).  Let’s continue that setup by configuring which attributes Azure AD will include in the assertions delivered to AWS.  From review of the AWS metadata we know that we need to  send claims of Role and RoleSessionName.  The RoleE will match to an an AWS IAM Role handling authorization of what we can do within AWS and the RoleSessionName provides a unique identifier for the user asserting the entitlement.

Back in the Azure AD Portal I’m going to click the option to View and edit all other user attributes.  The exposes the attributes Microsoft sends by default.  These include givenName, suName, emailAddress, and name.  Since the AWS metadata only requires RoleSessionName and Role, I’m going to delete the other attributes.  No sense in exposing additional information that isn’t needed!

pic19.png

After the extra attributes are deleted I create the two required attributes as seen in the screenshot below.

pic20.png

I’m now going to bounce over to the AWS Management Console.  After logging in I navigate to the Services menu and choose IAM.

pic21.png

On the IAM menu I choose the Identity providers menu item and hit the Create Provider button.

pic22.png

On the next screen I’m required to configure the identity provider settings.  I choose SAML from the drop-down box enter a provider name of MAAD and upload the IdP metadata I downloaded from Azure AD referenced earlier in the blog entry and hit the Next Step button.

pic23.png

On the next page I verify the provider name and the type of identity provider and hit the Create button.  Once that is complete I see the new entry listed in identity providers list.  Easy right?

pic24.png

We have an identity provider, but that identity provider needs some IAM roles to be associated with the identity provider that my fictional users can assert.  For that I go to the Roles section and hit the Create Role button.

pic25.png

On the next screen I select the SAML button as the type of trusted entity since the role is going to be asserted via the SAML trust with Azure AD.  Here I select the MAAD provider and choose the option to allow the users to access both the AWS Management Console and the API and then hit the Next: Permissions button.

pic26.png

As I referenced in my first entry to this series, the role I’m going to create is going to be capable of managing all EC2 instances.  For that I choose the AmazonEC2FullAccess policy template and then hit the Next:Review button.

pic267.png

On the last screen I name the new role AzureADEC2Admins, write a short description, and hit the Create Role button.

pic28.png

The new role is created and can be seen associated to the identity provider representing the trust between AWS and Azure AD.

pic29.png

Let’s sum up what we did for this entry.  We examined the key settings Microsoft exposes for configuration with the AWS integration.  We examined the Azure AD (IdP) and AWS (SP) metadata to understand which settings are important to this integration and what those settings do.  We examined an assertion generated out of Azure AD prior to any of the necessary customization being completed to understand what a canned assertion looks like.  Finally, we completed a majority of the tasks we need to complete on the AWS side to create the SAML trust on the AWS end and to create a role JoG users can asserts.  Are your eyes bleeding yet?

In my last post in this series I’ll walk through the rest of the configuration needed on the Azure AD end.  This will include going over some of the mistakes the Microsoft tutorial makes as well as covering configuration of Azure AD’s provisioning integration as to what it means and how we can effectively configure it.  Finally, we’ll put all the pieces of the puzzle together, assert our identity, and review logs at AWS to see what they look like when a federated user performs actions in AWS.

The journey continues in my fourth entry.

Integrating Azure AD and AWS – Part 2

Today I will continue the journey into the integration between Azure AD and Amazon Web Services.  In my first entry I covered the reasons why you’d want to integrate Azure AD with AWS and provided a high-level overview of how the solution works.  The remaining entries in this series will cover the steps involved in completing the integration including deep dives into the inner workings of the solution.

Let me start out by talking about the testing environment I’ll be using for this series.

lab.png

The environment includes three virtual machines (VMs) running on Windows Server 2016 Hyper V on a server at my house.  The virtual machines consists three servers running Windows Server 2016 with one server acting as a domain controller for the journeyofthegeek.local Active Directory (AD) forest, another server running Active Directory Federation Services (AD FS) and Azure AD Connect (AADC), and the third server running MS SQL Server and IIS.  The IIS instance hosts a .NET sample federated application published by Microsoft.

In Microsoft Azure I have a single Vnet configured for connectivity to my on-premises lab through a site-to-site IPSec virtual private network (VPN) I’ve setup with pfSense.  Within the Vnet exists a single VM running Windows 10 that is domain-joined to the journeyofthegeek.local AD domain.  The Azure AD tenant providing the identity backend for the Microsoft Azure subscription is synchronized with the journeyofthegeek.local AD domain using Azure AD Connect and is associated with the domain journeyofthegeek.com.  Authentication to the Azure AD tenant is federated using my instance of AD FS.  I’m not synchronizing passwords and am using an alternate login ID with the user principal name being synchronized to Azure AD being stored in the AD attribute msDS-CloudExtensionAttribute1.  The reason I’m still configured to use an alternate login ID was due to some testing I needed to do for a previous project.

I created a single test user in the journeyofthegeek.local Active Directory domain named Rick Sanchez with a user principal name (UPN) of rick.sanchez@journeyofthegeeklocal and msDS-CloudExtensionAttribute1 of  rick.sanchez@journeyofthegeek.com.  The only attribute to note that the user has populated is the mail attribute which has the value of rick.sanchez@journeyofthegeek.com.  The user is being synchronized to Azure AD via the Azure AD Connect instance.

In AWS I have a single elastic compute cloud (EC2) instance running Windows Server 2016 within a virtual private cloud (VPC).  I’ll be configuring Azure AD as an identity provider associated with the AWS account and will be associating an AWS IAM role named AzureADEC2Admins.  The role will grant full admin rights over the management of the EC2 instances associated to the account via the AmazonEC2FullAccess permissions policy.

Let’s begin shall we?

The first step I’ll be taking is to log into the Azure Portal as an account that is a member of the global admins and navigate to the Azure Active Directory blade.  From there I select Enterprise Applications blade and hit the New Application link.

entapps.png

I then search the application gallery for AWS, select the AWS application, accept the default name, and hit the Add button.  Azure AD will proceed to add the application and will then jump to a quick start page.  So what exactly does it mean to add an application to Azure AD?  Good question, for that we’ll want to use the Azure AD cmdlets.  You can reference this link.

Before we jump into running cmdlets, let’s talk very briefly about the concept of application identities in AAD.  If you’ve managed Active Directory Domain Services (AD DS), you’re very familiar with the concept of service accounts.  When you needed an application (let’s call it a non-human to be more in-line with industry terminology) to access AD-integrated resources directly or on-behalf of a user you would create a security principal to represent the non-human.  That security principal could be a user object, managed service account object, or group managed service account object.  You would then grant that security principal rights and permissions over the resource or grant it the right to impersonate a user and access the resource on the user’s behalf.  The part we want to focus in on is the impersonation or delegation to access a resource on the behalf of a user.  In AD DS that delegation is accomplished through the Kerberos protocol.

When we shift over to AAD the same basic concepts still exist of creating a security principal to represent the application and granting that application direct or delegated access to a resource.  The difference is the protocol handling the access shifts from Kerberos to OAuth 2.0.  One thing many people become confused about is thinking that OAuth handles authentication.  It doesn’t.  It has nothing do with authentication and everything to do with authorization, or more clearly delegation.  When we add an application the AAD a service principal object and sometimes application object (in AWS instance both are created) are created in the AAD tenant to represent the application.  I’m going to speak to the service principal object for the AWS integration, but you can read through this link for a good walkthrough on application and service principal objects and how they differ.

Now back to AWS.  So we added the application and we now have a service principal object in our tenant representing AWS.  Here is a few of the attributes for the object pulled via PowerShell.

awsservice.png

Review of the attributes for the object provide a few pieces of interesting information.   We’ll get to experiment more with what these mean when we start doing Fiddler captures, but let’s talk a bit about them now.  The AppRoles attribute provides a single default role of msiam_access.  Later on we’ll be adding additional roles that will map back to our AWS IAM roles.

Next up we have the KeyCredentials which contains two entries.  This attribute took me a while to work out.  In short, based upon the startDate, I think these two entries are referencing the self-signed certificate included in the IdP metadata that is created after the application is added to the directory.  I’ll cover the IdP metadata in the next entry.

The Oauth2Permissions are a bit funky for this use case since we’re not really allowing the application to access AWS on our behalf, but rather asking it to produce a SAML assertion asserting our identity.  Maybe the delegation can be thought of as delegating Azure AD the right to create logical security tokens representing our users that can be used to assert an identity to AWS.

The PasswordCredentials contains a single entry which shares the same KeyID as the KeyCredential.  As best I can figure from reading the documentation is this would normally contain entries for client keys when not using certificate authentication.  Given that it contains a single entry with the same KeyID as the KeyCredential for signing, I can only guess it will contain an entry even with a certificate is used to authenticate the application.

The last attributes of interest are the PreferredTokenSigningKeyThumbprint which references the certificate within the IdP metadata and the replyURLs which is the assertion consumer URI for AWS.

So yeah, that’s what happens in those 2 or 3 seconds the AWS application is registered with Azure AD.  I found it interesting how the service principal object is used to represent trust between Azure AD and AWS and all the configuration information attached to the object after the application is simply added.  It’s nice to have some of the configuration work done for us out of the box, but there is much more to do.

In the next entry I’ll walk through the Quick Start for the AWS application configuration and explore the metadata Azure AD creates.

The journey continues in my third entry.

Integrating Azure AD and AWS – Part 1

Hi everyone.  After being slammed with work from the real job over the past few months, I’m back with a new deep dive into the integration between Azure Active Directory (AAD) and Amazon Web Services (AWS).  I enjoyed the heck out of this one because I finally got some playtime in AWS and got to integrate two of the big cloud providers together to make some cool stuff happen.  There are a lot of blogs and articles out there (including Microsoft’s and Amazon’s *cough cough*) which provide the steps to accomplish this integration, but either the steps are incomplete, outdated, or wrong and none of them give a great explanation of the why or the how.  I can’t complain though, what else would I blog about?

Before we jump into the technologies that power the integration, let me first answer the question as to why we’d want to do the integration in the first place.

Let’s face it, managing digital identities is hard and it’s only getting harder with the introduction of cloud technology to the mix.  The tens of thousands of identities you’re managing for your users on-premises data center can quickly grow into the millions when SaaS comes into the mix. The operational overhead or supporting those millions of identities can eat up a large part of your IT budget and make your user experience miserable.  Beyond the cost issue, saddling your users with hundreds of credentials means users are going to re-use passwords and store them in whatever ways are convenient for them (under the keyboard anyone?) which introduces the risk of the credentials being compromised and sensitive data getting leaked.

Now more than ever you need to put a strong focus on centralized identity management and modern authentication and authorization.  Historically this was very challenging to do because of the lack of application programming interfaces (APIs) that allowed for create read update delete (CRUD) operations against the individual user records represented in an application database such as a SQL backend.  Beyond the lack of good APIs, you also were stuck using complicated and limiting legacy authentication and authorization protocols such as Kerberos, NTLM, LDAP, and the like.

Thankfully the industry has made a dramatic shift towards providing robust web-based APIs and support for modern authentication and authorization such as SAML, WS-Fed, Open ID Connect, and OAuth.  This presents a unique opportunity for organizations to shift towards a centralized identity management model where one authoritative store drives the lifecycle of an identity across all applications.  With the introduction of the modern protocols, users aren’t required to maintain thousands of credentials and can instead rely upon a singular trusted credential service provider (CSP) to act as the primary authentication point allowing users to then assert their identities to applications.  This frees the application from having to be saddled with storing and managing user credentials as well as improving the user experience, not to mention using these modern protocols is far simpler for your average developer.

Integrating AAD and AWS allow you to take advantage of centralized identity and modern authentication and authorization.  AAD specifically allows you to leverage all the cool features of a modern Identity-as-a-Service (IDaaS) offering such as behavioral analytics, multifactor authentication, adaptive authentication, and contextual-based authorization.  The short of it is you get a rock solid IDaaS to back the industry leading PaaS and IaaS offerings of AWS.  The best of both worlds right?

Now that you understand why you’d want to integrate the two solutions, let’s look at the technology powering the solution. In this integration the vendors are leveraging the concepts of modern APIs and modern authentication and authorization I touched upon above.  First up is authentication.

aws-signon

In this integration SAML, specifically the identity provider-initiated single sign-on POST binding, is being used to assert the user’s identity to the service provider (SP) after the user successfully authenticates with the identity provider (IdP).  Azure AD plays the role of IdP and AWS plays the role of SP.  The sequence of events plays out as follows:

  1. The user navigates to AAD and authenticates using either a credential or an asserted identity from a federated identity store.  The user then selects AWS from the listing of applications exposed through a method like the MyApps portal.  AAD generates an assertion containing a claim of the user’s identity and the AWS Identity and Access Management (IAM) role(s) the user is authorized to use and redirects the user to an endpoint at AWS.
  2. The user’s browser posts the assertion to the endpoint at AWS.
  3. The assertion is passed to the AWS security token service (STS) which checks the assertion to ensure it is from an identity provider that has been configured to be trusted for the AWS account, verifies the roles can be granted to a federated user, and completes the authentication process granting the user access to the AWS management console.(Don’t worry, we’ll dig into this process much more deeply using Fiddler in the next post.)

For provisioning, the AWS API is used.  AAD queries the AWS API using credentials for an AWS security principal that is associated with a role that has the IAMReadOnlyAccess permissions policy or greater.  It queries for the IAM roles configured for the account and synchronizes those roles back to AAD.  When the synchronization is complete, AAD users can then be added to the relevant roles from within AAD creating a one stop shop for doing your identity lifecycle management, authentication, and authorization.  Nice right?

At a high level that is the why and the what. In my upcoming posts in this series I’ll be digging deep into the how.  This will include how to do the integration, the pitfalls of the Microsoft tutorial, and of course Fiddler captures showing the conversations between the web browser, AAD, and AWS.

The journey continues in my second entry.

Helpful hints for resolving AD FS problems – Part 1

Hi everyone.

Over the past week I’ve been building a lab for an upcoming deep dive into Microsoft’s Web Application Proxy.  During the course of building the lab I ran into a few interesting issues with AD FS and the Web Application Proxy that I wanted to cover.  Some were similar to issues I’ve run into in production environments and some were new to me.

These issues are interesting in that there aren’t any obvious indicators of the problem in any of the typical logs.  Two out of three required some trial and error to determine root cause, while the third drove me quite insane for a good two weeks before getting an answer from an “official” source.  Over the course of this series of blogs I’ll cover each issue in detail with the hopes that it will help others troubleshoot these issues in the future.

Issue 1: AD FS Certificate authentication fails

I’m going to start with the problem that took me the longest to resolve and eventually required getting the answer directly from an official source.

For those of you that are unfamiliar, AD FS provides the capability to offer multi-factor authentication methods both native and third-party.  Out of the box, it supports certificate-based authentication as an option for a multi-factor or “step-up” authentication mechanism.

A few months back I wanted to take advantage of the certificate authentication feature to provide a two-factor authentication solution for applications integrated with AD FS.  Like a good engineer I did my Googling, read the Microsoft articles and various blogs out there to understand how the feature worked and what the requirements were.  I built a lab in Azure, setup an AD FS server, and ensured port 49443 was open in addition to the the typical ports required by AD FS.  I created my instance of AD CS, issued a user certificate containing the user’s UPN in the subject alternate name field, and setup a sample SAML app and configured it to require Certificate authentication.

How easy it all sounds right?  I navigated to the sample application and got the screen below…

Screen Shot 2017-06-04 at 9.29.35 PM

and I waited….  and waited…. and waited…  Ummm, what went wrong?  Well surely the AD FS log will tell me what happened.

Screen Shot 2017-06-04 at 9.34.03 PM.png

Well isn’t that odd.  No errors or warnings in the AD FS Admin log.  A quick check of the Application and System logs showed no errors either.  Maybe the AD FS Debug log would show me something?  I flipped on the log and attempted another authentication.

Screen Shot 2017-06-04 at 9.38.07 PM

Nothing as well?  Maybe the server can’t query the revocation lists designated in the certificates CDP?  Nope, not that either the server can successfully contact the CDP endpoints.  At this point I began to get quite frustrated and attempted packet captures, Fiddler captures, and anything and everything I could think of.  Nothing I tried revealed the answer.

I finally gave in (which I can tell you is incredibly challenging for me) and reached out to an “official” source.  We chatted back and forth and went through much of the same steps as outlined above to ensure I didn’t miss anything.  However, we ran into another dead end.  He then reached out to some other engineers he knew and eventually we got a hit.  We were told to check to see if there were any intermediary certificates stored within the trusted root certificate authorities store.  Sounds like an odd circumstance, but sure why not.

Upon opening up the certificates MMC, opening the machine store, and exploring the trusted root certificate authorities store low and behold I see an intermediary certificate within the store.  I deleted the certificate, restarted the AD FS server and attempted another login to the sample claim application and hit the screen below.

Screen Shot 2017-06-04 at 9.50.16 PM

Boom, I’m finally receiving the certificate prompt.  Clicking the OK button brings about the successful login below.

Screen Shot 2017-06-04 at 9.51.23 PM

So what was the issue?  Apparently AD FS certificate authentication fails without generating an error in any logical location (maybe nowhere at all?) if there is an intermediary certificate in the trusted root certificate authority machine store.  I’ve verified this is an issue in both AD FS 2012 R2 and AD FS 2016.  Now why this occurs is unknown to me.  It could be the underlining HTTPS.SYS driver that pukes and doesn’t report any errors to the event logs.  I didn’t get a straight answer as to why this occurs, just that it will due to some type of integrity check on the machine certificate store.  Odd right?

That completes the rundown of the first of three problems I’ll be outlining in this series of blogs.  Hopefully this helps save someone else some time and aggravation.

See you next post!