Quantcast
Channel: Active Directory Federation Services – Hybrid Identity
Viewing all 26 articles
Browse latest View live

Workplace Join failed 0x10dd (a.k.a. how to properly change/set your #ADFS certificates)

$
0
0

This post is really a simple layer-8 issue, but I thought it justified a post as there’s a nuance or two that are worth discussing.  I’m in the process of designing yet another Active Directory Federation Services deployment although this one is more interesting than some of my previous projects as it involves a lot of multi-factor authentication rules and configuration against a lot of trusts for a large user base.  While I’m authoring the design I like to essentially setup the design in my own lab, which is what brings me to this post.  I was enabling the Device Registration Services (DRS) in an existing Active Directory Federation Services (AD FS) 3.0 deployment and, having followed the small and simple set of well documented instructions, realised that my clients could not Workplace Join because the DRS essentially wasn’t there…

The WPJ event log on my Windows 7 desktop that is configured to automatically and silently WPJ showed this event:

image

And this:

image

Clicking that URL returns the browser “This page cannot be displayed” (as opposed to the actual XML when it works correctly) error.

Looks pretty clear.  There’s something really wrong with the DRS endpoint, i.e. it isn’t there (did I forget to enable DRS on each node?), or the DNS entry is wrong, etc.

So I take the URL and try hitting it on each local federation service server node (I have HOSTS entries on each node to hit self and avoid the internal load balancer).  The endpoint isn’t there.  No DNS issue, something else is up.  I dump the HTTP.SYS URLACL list (netsh http show urlacl) and I can see there’s a listener for this URL:

image

Rerunning Enable-ADFSDeviceRegistrationService doesn’t fix the matter.  It does complain about missing UPN suffixes but that’s expected as this is a multi-purpose lab and I have loads of UPN suffixes defined that won’t be used by WPJ clients.

image

I try hitting the https://enterpriseregistration.abstractsynapse.com/EnrollmentServer/contract?api-version=1.0 URL with the FS name instead, e.g.

https://federation.abstractsynapse.com/EnrollmentServer/contract?api-version=1.0 and that works.  I take a look at the certificate and the problem is now obvious.  This certificate doesn’t contain subject alternate name (SAN) properties.  Which is weird because I’ve just procured a new HTTPS certificate with multiple SAN properties to support DRS – as I said at the beginning, I was enabling DRS post-deployment.  My original deployment did not need DRS and therefore only had an SSL certificate with the FS name as the subject.  I have had to enrol a new certificate with multiple DNS SAN attributes for enterpriseregistration.<UPN suffix in use in the enterprise>.

And here’s the crux of the matter and the major layer-8 issue.  When I changed the AD FS certificate I did so using the following command on the primary FS:

Set-AdfsCertificate -CertificateType Service-Communications -Thumbprint “b5 9b d6 af 08 53 08 85 6e b8 aa 52 7b e3 15 65 87 66 e0 f5”

The problem is that command allows you to change the Service Communications certificate, the Token Signing certificate and the Token Encryption certificate.  That command does not change the SSL certificate!

To change the SSL certificate you must use Set-AdfsSslCertificate.  And unlike Set-AdfsCertificate you must do this on each FS node as it is configuring HTTP.SYS (we no longer do this in IIS).

image

Once done, the SAN attributes allow the HTTPS binding to work and the endpoint is live.  WPJ worked immediately then.

Lessons learned

When planning and designing AD FS consider future DRS needs.  Try and get the certificate right up front.  For many customers this is easy – they have a common and consistent UPN namespace, so just get the enterpriseregistration DNS SAN along with the DNS SAN for the FS name, e.g. for sts.contoso.com FS and users with @contoso.com UPN:

  • Subject: sts.contoso.com
  • SAN: DNS=sts.contoso.com
  • SAN: DNS=enterpriseregistration.contoso.com

For more complex deployments look to see what UPNs are in use.  In my experience DRS is closely aligned with cloud deployments and cloud deployments have a dependency on on-premises remediation that rationalises and remedies UPNs among other things.

When deploying the Device Registration Service, remember that the endpoints will only work if you have the correct DNS SAN attributes in your SSL certificate.  Check which certificate is in use using Get-AdfsSslCertificate and Get-AdfsCertificate -Type Service-Communications and also use the browser to validate, i.e. navigate to https://federation-service.domain-name.tld/federationmetadata/2007-06/federationmetadata.xml and look at the certificate in use by your browser – check the subject alternate name and subject fields and the thumbprint.

Lastly, deploying DRS consists of the following commands:

Primary FS (WID deployment):

  1. Initialize-ADDeviceRegistration (Initialise DRS in the AD DS forest – requires Enterprise Admins group membership)
  2. Enable-AdfsDeviceRegistration (Enable DRS on this server)
  3. Set-AdfsGlobalAuthenticationPolicy -DeviceAuthenticationEnabled $true (Enable device authentication in AD FS)

Secondary FS:

  1. Enable-AdfsDeviceRegistration (Enable DRS on this server)

In a SQL deployment you run the first set of commands on one node and the subsequent set of commands on all other nodes.

On your Web Application Proxy servers you might need to reconfigure the SSL endpoint listeners to listen on all of the SANs in your certificate.  You do this using Update-WebApplicationProxyDeviceRegistration.

Summary

When changing your AD FS SSL certificate remember you basically need to do this in two places for 99% of deployments:

  • You set the HTTPS certificate using Set-AdfsSslCertificate on each node in the farm
  • You set the Service Communications certificate using Set-AdfsCertificate on one server – in a WID deployment on the primary, in a SQL deployment on any node

You must also update your Web Application Proxy (WAP) servers, if they’re in play:

  • You set the HTTPS certificate for your WAP servers using the Set-WebApplicationProxySslCertificate cmdlet – again, as with Set-AdfsSslCertificate, this is done on each WAP node as it’s applying the configuration to HTTP.SYS
  • You update the HTTP.SYS endpoints using Update-WebApplicationProxyDeviceRegistration

This is important as the typical deployment pattern expects the service communications certificate to be the same as the federation service (SSL) certificate (it doesn’t have to be, hence the 99% of deployment statement). 

Note that even if you use the GUI you must remember to set the SSL certificate to correctly update the HTTP.SYS bindings.



The use of Distributed Key Manager (DKM) in Active Directory Federation Services (AD FS)

$
0
0

Something that crops up quite a lot when you’re involved in planning and designing an Active Directory Federation Services (AD FS) infrastructure is certificates and, for those of you who have worked anywhere where you have to justify your design to various control and governance authorities (think banks, government and defence for sure), what the certificates do and how they are controlled and protected.  Many people take for granted that an AD FS farm shares a set of common certificates.  Some have wondered how AD FS shares the private keys for the signing and encryption certificates.  Others have wondered why is there a bunch of containers with some blobs in some of the attributes created and maintained in the Active Directory Domain Services (AD DS) domain.

Well, hopefully I can explain this.

The token signing and token decryption certificates, including the corresponding private keys, are stored in the AD FS configuration database.  The certificates are encrypted using a technology called Distributed Key Manager (DKM).  AD FS creates and uses these DKM keys as and when needed, which basically means when you initialise the farm and when a key expires.

During the initial configuration of an AD FS farm the FS farm creation process creates a dedicated container in the on-premises AD DS domain of the account installing AD FS (which should be in the same domain as the service account for AD FS otherwise the service account can’t locate the container and will fail to start) to store a master encryption key using the aforementioned DKM solution (a more detailed explanation of the cryptography aspects of DKM can be found here).  This container is permissioned such that only the FS service account can read the key.

When a new certificate requires creation (either initially, during setup, or in an automatic roll over scenario), one of the nodes is elected to perform the following task:

  1. The server generates the certificate and stores it in the service account’s certificate store (the MY store for the service account)
  2. The certificate (the .PFX structure) is serialised; encrypted with the master key generated during farm initialisation, using DKM client APIs; and stored in the configuration database

When the AD FS service starts on one of the nodes the following happens:

  1. The server decrypts the table that contains all encrypted certificate information using the DKM client API
  2. The deserialised certificate is then stored in the service account’s certificate store on the local server

Lastly, the encryption key used by DKM, stored in AD DS, expires after a year.  AD FS manages the creation of a new key – AD FS uses a valid DKM key to encrypt the PFX to store in it’s configuration database; if a valid DKM key is not present, AD FS creates a new one.

So, in summary:

  • The token signing and decryption certificates are stored as PFX blobs in the AD FS configuration database
  • The table that houses the blobs is encrypted using a technology called Distributed Key Manager (DKM) and the DKM master key(s) are stored AD DS
  • The DKM master keys are created when required, i.e. during farm initialisation and when they expire
  • AD FS servers retrieve the DKM master key from AD DS and use this to decrypt the encrypted table in the AD FS configuration database; the decrypted PFX is installed into the MY store of the AD FS service account
  • Only the AD FS service account has permissions to read the key material stored in AD DS and only the AD FS service account has permissions to read certificates in its MY store by default
  • All federation service servers in the AD FS farm share the same token signing and decryption certificates

I hope you find this useful.  Special thanks to Ramiro Calderon for his assistance in making sense of this process.


Azure Multi-Factor Authentication (#AzureMFA) and Active Directory Federation Services (#ADFS)

$
0
0

Today, implementing Azure Multi-Factor Authentication (MFA) in an hybrid identity and access management solution based on Azure Active Directory (Azure AD, AAD) and Active Directory Federation Services (AD FS) more often than not requires that you implement the on-premises Azure MFA Server component.  This is because you typically have relying party (RP) trusts established in your on-premises AD FS federation service.  That is, you have some Software-as-a-Service (SaaS) apps that authenticate via AD FS and not Azure AD.  In order to introduce Azure MFA into the authentication process for these apps you require a secondary authentication provider deployed within AD FS.  Smaller deployments can install the MFA Server component directly on the federation service (FS) servers; larger deployments, i.e. more than two FS, will generally build out a load-balanced Azure MFA Server “farm” and utilise the Azure MFA “adapter” (the secondary authentication provider) to talk to Azure MFA Server via the load-balanced VIP (virtual IPv4 address).

I’ll provide a couple of drawings, to illustrate what I’m talking about.  Firstly, here’s the on-premises scenario – SaaS, AD FS and MFA Server.  In this case Azure MFA Server is mandatory – it’s no different to implementing any other MFA technology.  The cloud can’t really help with this use case today.

image

If you have an hybrid Azure AD and AD FS IdP then this is what it looks like: Azure AD, AD FS and MFA Server authenticating an Azure AD-hosted SaaS app.  In this case Azure MFA (cloud) is not used and again Azure MFA Server (on-premises) is because it’s a hybrid environment – it factors the AAD SaaS (and first-party) apps as well as on-premises apps.

image

If you’re building this now, especially if it’s for AD FS-only purposes, then this pattern is somewhat frustrating, more so if you have users registered with Azure MFA (the cloud service) or even Azure Password Management.  You cannot migrate registration data between cloud and on-premises (or between on-premises and the cloud) so you end up having to go all-out and deploy on-premises MFA Server, user and mobile registration portals, localisations and then manage the end-user communications and helpdesk management as well as the directory synchronisation.  Not ideal.  One example, I had to add eight (8) additional servers to an existing (I previously deployed) twenty (20) node AD FS deployment (8 FS, 8 WAP, 4 SQL) – 28 servers in total!

Which is why Windows Server 2016 Active Directory Federation Services (AD FS 2016) has a new and improved Azure MFA secondary authentication provider.  AD FS 2016 ships with a built-in “connector” for Azure MFA that talks directly to the cloud service and negates the need for any on-premises MFA Server infrastructure.  As long as the identities that AD FS is authenticating are synchronised to your Azure AD everything is in place.  Furthermore, AD FS 2016 actually enables Azure MFA as a primary authentication mechanism!  What does that mean?  It means that if you register the Azure Authenticator app, next time you access an AD FS protected resource you can authenticate by providing your username and the one-time-pin (OTP) code from the app.  No password!  This is one of several key new features arriving in AD FS 2016 that negate the need for users to provide credentials in the form of passwords!  I’ll blog about all of the no-password features in a separate post.  For now my focus is the Azure MFA [cloud] “adapter”.

May 2016 (Windows Server 2016 Technical Preview)

Windows Server 2016 Technical Preview 5 shipped a little while back.  When it shipped the Azure MFA secondary authentication provider was in private preview.  As of the 17th of May, 2016, the preview is public.  This means WS 2016 TP5 gives you everything you need to deploy Azure MFA as a primary or secondary authentication provider!

The official documentation was a few days behind the actual transition from private to public but is there now.  Here’s the URLs:

Configuration/deployment

I won’t re-document the configuration steps here, I’ll just summarise the actual process:

  1. For each federation service server/node in your AD FS farm, you create a certificate that will be used to authenticate with Azure MFA.  AD FS provides a PowerShell cmdlet for this – New-AdfsAzureMfaTenantCertificate
  2. Each certificate is assigned to an Azure AD Service Principal by creating a service principal credential.  This is done via New-MsolServicePrincipalCredential and is no different to assigning a credential to an Azure Web App or Web API, etc.  The app principal ID is a constant – it’s 981f26a1-7f43-403b-a875-f8b09b8cd720.
  3. Lastly, once you’ve created a cert for each FS node and created a service principal credential for each cert you configure the Azure MFA provider using another AD FS PowerShell cmdlet – Set-AdfsAzureMfaTenant.  This operation is performed once per farm and can be run from any node.

Once this configuration is done you’re ready to start configuring additional authentication policies for RP trusts other than urn:federation:MicrosoftOnline (The Azure AD/Office 365/MSOnline) trust.  For the Azure AD trust you configure the SupportsMfa Boolean property of each federated domain (Set-MsolFederatedDomain) and utilise Conditional Access Policy (CAP) to invoke MFA for Azure AD apps (SaaS, PaaS, App Proxy and first-party apps).  When using Azure MFA there is no need to offload MFA to AD FS – you just use the cloud.  This is different – the inverse – from the AD FS 2012 R2 and AAD hyrbid model.

Caveats and limitations

There are some features missing.  You have to enable (or enforce) at the per-user level if you want an in-line registration experience.  Per-app MFA with automatic “in-line” registration is not available.  You obviously cannot only utilise Azure MFA as a primary authentication provider either, so the typical pattern will be to enable in isolation for the extranet and utilise IWA and/or FBA for the intranet.

The per-user model is particularly frustrating.  It effectively mandates the use of app passwords which are difficult to deploy and use.  The alternative is getting users to register themselves and then utilising CAP, however as this will break non-registered users I can’t see this being a suitable option either.  Time will tell how useful this is and whether it is a sufficiently flexible implementation that truly negates the need for an on-premises MFA Server setup.

Summary

Prior to Windows Server 2016 integrating Azure MFA with on-premises SaaS apps that authenticate using AD FS required an on-premises implementation of Azure MFA Server

Windows Server 2016 (starting in public preview in Technical Preview 5) introduces a new and improved secondary authentication provider for Azure MFA that does not require any on-premises components.  The “adapter” talks directly to the cloud service; configuration of all MFA properties are managed in the cloud (it’s a hybrid of on-premises and cloud when you use the on-premises MFA Server).

In addition to negating the need for on-premises MFA components AD FS 2016 also introduces additional authentication scenarios for Azure MFA customers.  Namely, as part of the drive to never require a password when accessing corporate resources from outside of the corporate network, AD FS 2016 supports Azure MFA as a primary authentication provider, which means users can sign-in to AD FS-protected resources using their username, e.g. pawill@contoso.com, and their Azure Authentication one-time-pin (OTP) code.


Active Directory Federation Services (#ADFS) Single Sign On (SSO) and token lifetime settings

$
0
0

To understand Single Sign-On (SSO) and Persistent Single Sign-On (PSSO) in Active Directory Federation Services (AD FS) you must first understand the authentication cookie.  After the initial logon is validated an authentication cookie is written to the client (typically a browser). These cookies are implementation-specific and opaque to intermediaries and the user, including the federation service proxy for example. Subsequent authentication is done using the cookie and does not necessitate recapturing credentials or re-authenticating via the original means, e.g. forms-based or Kerberos/NTLM.

This is important.  The cookie allows for subsequent authentication without recapturing credentials.  In other words, the process is invisible or transparent to the user.  The user is still authenticating, there’s still round trips back to the authentication service, but the user is not bothered – it’s seamless – it’s SSO.

Within the AD FS authentication and token issuance flow the FS writes the authentication cookie to the client as a session cookie by default. The cookie contains a signed token and a set of claims in-line with the claims issued by the Active Directory Domain Services (AD DS) Claims Provider trust (or any other CP in the federated scenario).  Session cookies are bound to the session.  When the parent process, i.e. the browser, is terminated the session is destroyed.  Thus, regardless of the validity of the token, you kill all instances of your browser, for example, and the token is destroyed.

When a client requests a security token for a relying party (RP) from the FS the authentication cookie is used to authenticate to the FS and initialise or bootstrap the set of input claims for token issuance. This cookie provides SSO. An example being a client authenticates with AD FS and gets a token to an application, e.g. Azure AD, and then attempts to access another app, for example an on-premises federated app; the client already has a valid authentication token in the form of the cookie and therefore is able to SSO to the FS and obtain a new security token for the federated app.

Persistent Single Sign-On, or PSSO

PSSO is basically an authentication cookie that persists across sessions. By default, authentication cookies are session-based, which means when the browser closes the cookie is destroyed. PSSO cookies are written to Workplace Joined (WPJ)/registered devices by default, i.e. devices that have registered using Azure Device Registration Services (DRS) and been written back to the on-premises Active Directory Domain Services (AD DS) forest by Azure AD Connect (hybrid model); or registered directly using Windows Server 2012 R2 Device Registration Service (on-premises model).

AD FS will also set PSSO cookies if Keep Me Signed In (KMSI) is selected during the authentication process.

In addition, AD FS emits a PSSO claim type of http://schemas.microsoft.com/2014/03/psso with a value of “true”.  The PSSO claim can be sent to Azure AD so that AAD and SharePoint Online honour the configuration too, i.e. AAD will issue PSSO cookies as a result of this being configured in AD FS.  This is done by adding the following custom claim rule to the Azure AD (urn:federation:MicrosoftOnline) relying party trust:


psso:[Type == "http://schemas.microsoft.com/2014/03/psso"]

 => issue(claim = psso);

SSO (and PSSO) settings

The AD FS 2012 R2 settings for SSO and PSSO are as follows:

  • SSO lifetime is 480 minutes (8 hours) – configurable at the global/AD FS level (SsoLifetime property)
  • PSSO is enabled – global configuration (PersistentSsoEnabled)
  • KMSI is disabled – global configuration (KmsiEnabled)
  • PSSO lifetime for registered devices is 10,080 minutes (seven days) – global configuration (PersistentSsoLifetimeMins)
  • PSSO lifetime for KMSI is 1,440 minutes (24 hours) – global configuration (KmsiLifetimeMins)

All of the above are global settings, read using Get-AdfsProperties and managed using Set-AdfsProperties.

What about the actual tokens issued?

  • Token lifetime is 60 minutes (1 hour) – configurable at the Relying Party (RP) trust level (TokenLifetime)

The RP settings are read using Get-AdfsRelyingPartyTrust and managed using Set-AdfsRelyingPartyTrust.  The default value, when read, is zero, which actually means 60, as the property expects the configured value in minutes.

There’s another RP-specific setting worth calling out too:

  • AlwaysRequireAuthentication – when true (false by default) the SSO cookie is ignored and a credential capture is mandated

Important note

If you authenticate using IWA then the re-authentication (credential capture) is invisible – it’s SSO – so you won’t see much from a UX perspective, but you’ll have a fresh and valid 60-minute token.

Always Require Authentication is particularly useful if you require Multi-Factor Authentication (MFA) for a sensitive app.  Regardless of SSO/PSSO state, if you mandate MFA and Always Require Authentication for an RP then each time you need a token for that app you will MFA.

Changes in Windows Server 2016

Active Directory Federation Services 2016 changes some of the above settings.  There’s a new TechNet document describing the registered devices and non-registered devices SSO settings:

I’ll describe the information here for posterity purposes.

  • Registered devices.  By default, users with registered devices will get SSO for up to a maximum of 90 days if they use their device to access AD FS resources within a 14 day window.  This behaviour is controlled by two new settings/values:
    • Maximum SSO period (PersistentSsoLifetimeInMins – default value is 60,480)
    • Device Usage Window (DeviceUsageWindowInDays – default value is 14)
  • Non-registered devices.  For non-registered devices SSO and PSSO is managed using KMSI settings, as is true of AD FS 2012 R2.
    • If KMSI is disabled the SSO cookie has an 8-hour validity (SsoLifetime property of the RP trust).
    • If KMSI is enabled the SSO cookie has a 24-hour validity (KmsiLifetimeMins – default value is 1,440; property is global; maximum upper value is 7 days)

Summary

AD FS 2012 R2 and AD FS 2016 tokens have a one hour (sixty minute) validity period by default.  This value is configurable on a per-relying party trust basis.  Token issuance requires that the token requestor has been authenticated by AD FS and has authorisation to request a token.  When a user is authenticated by AD FS an authentication cookie is written to the client to provide an SSO period, and subsequent requests to AD FS utilise this SSO period (authentication cookie).  The default value for the SSO period is 8 hours and is configurable at the global AD FS level.  If Keep Me Signed In is enabled and selected by the requestor, the SSO lifetime increases to 24 hours by default.  This value is configurable, globally, up to a maximum of 7 days.  If the requestor is authenticating from a registered device the SSO lifetime increases to 7 days in AD FS 2012 R2 and 90 days in AD FS 2016.  The 90 day validity requires an authentication within a 14 day period known as the device usage window, which means if you don’t access an AD FS application for more than 14 days then credentials will need to be recaptured, i.e. the SSO cookie is invalidated.

Lastly, you can configure a property of an RP trust to force authentication every time a token is requested.  That is, by enabling Always Require Authentication you configure AD FS to ignore SSO cookies for the configured trust(s).  This is useful when you want to deploy and utilise PSSO but need to mandate MFA for high-value assets.


Multi-Factor Authentication and multiple identity providers

$
0
0

When you implement an additional authentication provider in your Active Directory Federation Services (AD FS) identity provider (IdP) you soon start getting all manner of requests from application owners/managers within the business for multi-factor authentication (MFA) configuration.  For the most part it’s nice and easy, each application has one or two requirements such as “MFA when accessing from outside of the corporate network” or “MFA for admins”, so you create a couple of additional authentication rules on the relying party trust for the app.  This is nice and clean because there’s typically a one-to-one relationship between web application and federation service.  For example, consider the following architecture diagram – two SaaS apps, each implemented within the idp.contoso.com federation service (FS) as a relying party trust, or RP:

image

This is, in effect, a type of conditional access.  The AD FS claim rules allow you to implement a number of scenarios, for example:

  • Require MFA when accessing SaaS app #1 from outside the corporate network
  • Require MFA when accessing SaaS app #2 if you are not requesting a token from a registered device, i.e. a Workplace Joined (WPJ) or InTune-managed device
  • Require MFA when accessing SaaS app#1 and/or SaaS app#2 if you are an administrator of the app (designated by group membership in AD DS)

I won’t go over conditional access here – I have another post on that subject coming soon – and Ramiro does an awesome job of describing additional authentication rules in this post.  Suffice to say, there’s a lot of flexibility when it comes to controlling MFA in AD FS 2012 R2 and AD FS 2016 when the application in question trusts your FS directly.

Issues arise when the client needs to make a second hop for authentication however.  That is, when the SaaS app trusts an IdP that is not your FS and that IdP trusts your FS, as is the case in the following scenarios:

  • Azure Active Directory apps and federated users
  • Application or location specific federation services that support your corporate users
  • Partner organisations that trust your corporate users

The latter bullet is not really relevant here, but I am constantly coming across the first two points.  Take the following architecture illustration as an example.

image

What have I drawn?  Four web or SaaS apps and three different identity providers all of which actually support your corporate users.

  • Firstly, external web app #1 and #2 trust a specific federation service that has two claims provider trusts: one for a custom STS or FS that handles external users, hosted in a Linux LDAP directory; the other being your corporate IdP that handles corporate user authentications.
  • Next, SaaS app #1 is an Azure AD pre-integrated app, i.e. it trusts AAD for authentication, however your Azure AD tenant contains both managed (cloud) and federated identities, where the federated identities are your on-premises corporate users and the cloud identities are non-IT staff, e.g. factory workers, that need access to at least one of your SaaS apps.
  • Lastly, SaaS app #2 is a typical federated application that trusts your AD FS IdP.  Here you get SSO to your SaaS apps using your on-premises identities, i.e. your Active Directory Domain Services (AD DS) users.

Integrating MFA now just got a lot more complex (for a subset of your apps).

I want to gloss over Azure AD because I have another post planned for a more detailed discussion around Conditional Access Policy, or CAP.  So for AAD we’ll just say if you want MFA you need to control or configure that within Azure AD – this is Conditional Access Policy in AAD and it’s powerful, granular and the scope of what is included is growing.

And as we discussed at the start of this post, the SaaS app that directly trusts AD FS is obvious and easy – that’s just additional authentication rules.

However, if you have apps that trust an FS that in turn trusts your FS and those application owners want some of the MFA action then you have a bit of a problem, and this is really the reason I wanted to write this post.  To be clear, we’re specifically talking about this section of the architecture:

image

The issue that often confuses people is what the IdP is actually doing.  If we quickly summarise the flow of authentication, it goes like this:

  1. User/client hits the web app and is redirected to the IdP for authentication (the first FS – sts.contososervices.com)
  2. User selects realm and is redirected to the corporate FS/IdP (the second FS – idp.contoso.com).
    • (Users typically interact with the FS to perform Home Realm Discovery (HRD) a.k.a. IdP discovery – in the above case this involves a custom page with a button for external users and another button for corporate users.)
  3. User authenticates with the second FS (idp.contoso.com) and is issued a token for the first FS/IdP and is redirected back to the first IdP
  4. User authenticates with the first FS (sts.contososervices.com) using the token issued by the second FS and is then issued a new token for the web app and redirected back to the web app
  5. User is authenticated using the second security token – the token from the first IdP

All of this happens through java-script initiated browser redirects and HTTP POSTs.  The request for a token to the first IdP from the second IdP (a request for a SAML token for sts.contososervices.com, issued by idp.contoso.com) has no information relating to the actual app the user is hitting.  Only when the first IdP is issuing a token for the app is there any real information available about the app.  When authenticating with the second FS the app is technically the first FS.

So making a decision about whether to invoke MFA or not is not really the responsibility of the second – the corporate – FS.  The corporate FS/IdP cannot accurately make the right decision as it is simply issuing a token for another IdP (although it’s just another relying party to the FS).  What options exist then?  Assuming that you don’t want to discuss the obvious answer which is implement MFA at the first FS.

Options for implementing MFA for an app that indirectly trusts your FS/IdP that integrates with your MFA system

Note – I use the terms federation service (FS) and identity provider (IdP) interchangeably throughout this (and other) posts.  As far as I am concerned they are synonymous.

  • The easiest answer is to require MFA for members of one or more groups.  This is typically done via an equality match on the value (which is a string representation of a SID) in the http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid claim type
    • The benefit here is you lump users into a group and they get MFA
    • The disadvantage here is that the users might be using other applications that do not require MFA and will still be expected to undergo MFA each time they get their SSO token from the corporate AD FS (once per day or once per browser session, depending on usage)
    • You can control whether or not to invoke MFA based on endpoint here too, so you can permit browser-based authentication and bypass MFA for applications that talk directly to WS-Trust endpoints – this may or may not be a good thing as you can stop apps from breaking but obviously negate the security benefit of the secondary authentication
  • Another option is that the application can request MFA itself, i.e. the federation service simply honours the request.  This is typically done within the application itself.  Options are:
    • The application actually inspects the claims in the authentication token and determines whether or not MFA is needed, e.g. it looks to see if there’s an MFA authentication type value (http://schemas.microsoft.com/claims/multipleauthn) in the http://schemas.microsoft.com/claims/authnmethodsreferences claim type and perhaps also takes a look at the value of http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork claim type or maybe checks to see what role the authenticated user holds and, if the logic is such that you determine MFA is required, the app asks the IdP for MFA via the WAUTH (WS-Federation) or RequestedAuthNContext (SAML) request parameter.  This is generally known as step-up authentication.  In summary, your code looks for whether or not you have done MFA (you must issue the AuthNMethodsReferences claim to the app) and requests it if you have not and it feels it is needed.  Again, Ramiro does a quality job of describing this with a .NET MVC example here.
    • If the app simply requires MFA regardless of condition, then it can build the original sign-in request containing the WAUTH request parameter.  You can find a nice succinct discussion on the topic in this TechNet wiki article.
  • Beyond this you need to start venturing into the grey area of support that I like to think of as creative territory.  Sure, it’s fun and you can make it work, but it’s unlikely to be an operationally sound option going forward.
    • For example, you can look to rewrite the URL between the RP and the first FS and add the WAUTH query string, which the FS will honour.  In one customer case I did a basic POC here, because the first FS was running AD FS 2.0 and therefore had IIS locally, so an HTTP Module simply added the WAUTH query string if it wasn’t there.
    • You can also bake a “smart URL” where you craft the request yourself and again the FS will honour it, e.g. https://sts.contososervices.com/adfs/ls/?wa=wsignin1.0&wtrealm=urn:federation:dumpclaims&wauth=http://schemas.microsoft.com/claims/multipleauthn – users hitting this URL will undergo MFA and logon to the app, however you have to be sure that users will access the app via the URL.

What about invoking MFA at the first FS for users coming from the CP trust?  (In other words, what if we look for users authenticating from the second FS and invoke MFA for the app here?)

If you try to do this using additional authentication rules as you would a user in the same realm as the FS (i.e. your AD DS forest or trusted forest) then this won’t work in AD FS 2012 R2.  The request for MFA is ignored.  It is not bounced back to the IdP.  However, AD FS 2016 changes this…

AD FS 2016 exhibits the same behaviour as AD FS 2012 R2 by default.  But this behaviour is configurable.  There are two properties of interest:

  • On the relying party trust, the Boolean property RequestMFAFromClaimsProviders – set this to TRUE and the RP authentication rules will fire for claims provider trusts that support MFA (for CP trusts that do not support MFA, then you will either get an access denied when requesting your token or will get your token without MFA, depending on the access policy)
  • On the claims provider trust, the Boolean property SupportsMFA – set this to TRUE and the redirect to the claims provider will include the WAUTH parameter with the multipleauthn value which will request MFA (just like Azure AD does when your federated domain has SupportsMFA set to true)
    • If your upstream FS is not AD FS or doesn’t support the multipleauthn value in WAUTH you can specify the URI that will trigger MFA using the property CustomMFAUri

So, to answer the original question, upgrade sts.contososervices.com to AD FS 2016 and configure per-app MFA on each in-scope RP trust and make use of the above properties to get idp.contoso.com to perform the MFA.

Summary

Controlling multi-factor authentication via conditional access policy is a very powerful feature of AD FS.  The scope of AD FS conditional access policy must be fully understood, however.  AD FS can make granular decisions to allow or deny access to a trust or require MFA to a trust based on the set of claims available to the policy engine.  The important point here is that this configuration is made at the trust level, which is generally an application and occasionally two or three apps that are typically categorised the same.  If there’s an intermediary federation service, such as Azure AD (in the use case where you utilise federated users to access AAD SaaS apps, for example) or another federation service between your AD FS IdP which handles MFA and the app then you have no ability to determine what application is requesting the token and therefore your decisions only relate to the FS that you are getting a token for, which complicates your ability to define per-app MFA policies.  I have described some options in this space, but in reading them it should be obvious that the answer lies either within the app itself (generally not appropriate other than for administrative step-up) or the intermediary FS.  This is important.  I will cover off conditional access policy in more depth soon, but the purpose of this post want to highlight why your AD FS with MFA server can’t help mandate MFA for app #1 and not app #2 that trust an IdP (FS) that trusts yours.  The good news is that AD FS 2016 can be a big help here…


#ADFS and #MFA load balancer guidance

$
0
0

When designing Active Directory Federation Services (AD FS) my actual involvement with the networking guys who handle the load balancer configuration is generally limited to a few calls and emails.  We provide some requirements in the forms of availability and persistence or stickiness and they do what needs to be done.  Truthfully, you get a high-level architectural view of the various solutions which helps with subsequent designs as you have a bit of experience of pitfalls from past engagements.  This post is nothing prescriptive.  I’m no expert with BigIP, Cisco or Brocade.  But I do know AD FS and I do want to talk about a nuance that can change the basic persistence recommendations.

Recommended practices

AD FS.  Generally you’ll have an internal (corpnet) Virtual IPv4 (VIP) for federation service (FS) servers and an external (Internet-facing) VIP for the Federation Service Proxy (FS-P).  The VIP often supports both HTTP and HTTPS protocols, although most deployments are 95-100% HTTPS.  The persistence or stickiness setting is generally NONE.  AD FS is stateless and does not require client session affinity.  The load balancer needs to do what it does to keep the TLS connection alive, but beyond that there is nothing application specific that requires affinity.

MFA Server.  This topology can vary a little, but I typically have two corpnet VIPs – one for the SDK WS, one for the user portal; and one external VIP for the user and mobile portals.  These VIPs only really need to be HTTPS but I like to use both HTTP and HTTPS and redirect HTTP to HTTPS.  These VIPs require session-based affinity, and generally we use source-IP.

Let me draw what an AD FS IdP with MFA Server looks like to summarise the above.

image

What am I trying to convey here? 

  • DC#1-WAP and DC#1-PTL(EXT) are the external (Internet-facing) VIPs – WAP is the FS-P and PTL(EXT) is the User and Mobile portals
  • DC#1-FS, DC#1-MFA and DC#1-PTL(INT) are the internal (corpnet) VIPs for AD FS, MFA (SDK WS) and User portal
  • The MFA-related VIPs have persistence/affinity/stickiness; the AD FS VIPs do not

Deviation from typical in a complex deployment

This is all well and good for most deployments.  However I have recently seen an intermittent issue with SMS OTP in this topology that resulted in us having to introduce source-IP based stickiness at the corpnet FS VIP.  Here’s why…

In my deployments there are too many FS servers to consider installing the MFA Server onto, so I always use the MFA Server secondary authentication provider, a.k.a. “AD FS Adapter”.  This talks to the SDK WS, which is load balanced.

The FS-P (WAP) talks to any AD FS server via the FS VIP.  Payload is sent, response received and job done.  FS-P uses connection pooling and can and will talk to one of several FS servers and with round-robin distribution and no stickiness the FS can and will change.

Now, when a user is authenticating from the Internet and is therefore interacting with the FS-P and MFA is invoked and the user’s chosen MFA mechanism is one-way SMS there can be a valid delay between the initial authentication with username and password and the OTP being entered.  What we saw was that sometimes the FS-P would send the user-input OTP to a different FS than the one that the primary authentication happened with.  This is not at all desirable.  The FS that performed the primary authentication invoked the MFA and as such is the only server that can accept the OTP because only the MFA Server that initiated the OTP from the cloud service holds the OTP – the OTP is not written to the data file.  When the FS-P uses a different connection to another FS the FS sends the OTP to a different MFA Server which rejects it because it has no knowledge of that OTP, so authentication fails.

The solution is to turn on stickiness at the FS VIP so that the FS-P servers maintain connections with the same FS.  The FS servers are already seeing consistent and persistent sessions with the MFA Server servers.

Let me try and draw this just to be super clear.

image

  • First, the blue arrow shows our on-premises federated user authenticate via FS-P (WAP01) which talks to FS01 which in turn talks to MFA01 which invokes one-way OTP.
  • Secondly, the red arrow shows our user enter her OTP at WAP01 which communicates with FS03 which in turn communicates with MFA03 which has no knowledge of the OTP.

Summary

If you are using a deployment of AD FS 2012 R2 or AD FS 2016 and Azure MFA Server and the secondary authentication provider for MFA Server known as the AD FS adaptor and you allow one-way SMS as a means of authentication then you have to ensure SSL/TLS stickiness/affinity/persistence between FS-P (WAP) and FS (AD FS) in addition to stickiness on the MFA SDK web services VIP.

Impact

I first encountered this issue with a hybrid IdP (Azure AD Premium and AD FS as described above) with a significant user base (~100,000 active users across multiple geographies) and a medium to large number of federated applications (~100) during the post go-live phase of rolling out the MFA Server and Conditional Access Policies.  Our concern at the time was that implementing stickiness on the FS VIP could result in multiple FS-P servers getting a sticky session to a single FS which would result in an uneven load distribution.  We weren’t too bothered that the FS servers themselves couldn’t handle it – they can, we just didn’t want to see big spikes on a small set of the servers.  Our concerns were unfounded.  We had the luxury of Azure AD Connect Health giving us a rich set of easily digestible performance data and we monitored it closely when we made the change to the VIP and for a week or so after and we saw no ill effects.  Hence the reason I’m happy to post this recommendation as I’ve since deployed another similar hybrid IdP and am now designing another and have to commit this recommendation to those designs.

I hope this helps.  (And I hope it makes sense.)  Smile


Viewing all 26 articles
Browse latest View live