Background
Those who have rolled out Azure MFA (in the cloud) to non-administrative users are probably well aware of the nifty Trusted IPs feature. For those that are new to this, the short version is that this capability is designed to make it a little easier on the end user experience by allowing you to define a set of ‘trusted locations’ (e.g. your corporate network) in which MFA is not required.
This capability works via two methods:
- Defining a set of ‘Trusted” IP addresses. These IP addresses will be the public facing IP addresses of your Web Proxies and/or network gateways and firewalls
- Utilising issued claims from Federated Users. This uses the insidecorporatenetwork = true claim, sent by ADFS, to determine that this user is coming from a ‘trusted location’. Enabling this capability is discussed in this article.
The Problem
Now, the latter of these is what needs further consideration when you are looking to moving to the ‘modern world’ of Windows 10 and Azure AD (AAD). Unfortunately, due to some changes made in the way that ‘Win10 Domain Joined with AAD Registration (AAD+DJ) machines performs Single Sign On (SSO) with AAD, the method of utilising federated claims to determine a ‘trusted location’ for MFA will no longer work.
To understand why this is the case, I highly encourage that you first read Jairo Cadena‘s truly excellent blog series that discuss in detail around how Win10 AAD SSO and its associated services works. The key takeaways from those posts are that Win10 now has this concept of a Primary Refresh Token (PRT) and with this approach to authentication you now have the following changes:
- The PRT is what is used to obtain access tokens to AAD applications
- The PRT is cached and has a sliding window lifetime from 14 days up to 90 days
- The use of the PRT is built into the Windows 10 credential provider. Both IE and Edge know to utilise the PRT when communicating with AAD
- It effectively replaces the ADFS with Integrated Windows Auth (IWA) approach to achieve SSO with Azure AD
- That is, the auth flow is no longer: Browser –> Login to AAD –> Redirect to ADFS –> Perform IWA SSO –> SAML Token provided with claims –> AAD grants access
- Instead, the auth flow is a lot more streamlined: Browser –> Login and provide PRT to AAD –> AAD grants access
Hopefully from this auth flow change you can see why Microsoft have done this. Because the old way relied on IWA to perform ‘seamless’ SSO, it only worked when the device was domain joined and you had line of sight to a DC to perform kerberos. So when connecting externally, you would always see the prompt from the ADFS forms based authentication. In the new way, whenever an auth prompt came in from AAD, the credential provider could see this and immediately provide the cached PRT, providing SSO regardless of your network location. It also meant that you no longer needed a domain joined machine to achieve ‘seamless’ SSO!
The side effect though is that because the SAML token provided by ADFS is no longer involved in gaining access, Azure AD loses visibility on those context based claims like insidecorporatenetwork which subsequently means that specific Trusted IPs feature no longer works. While this is most commonly used for MFA scenarios, be aware that this will also apply to any Azure AD Conditional Access rules you define that uses the Trusted IPs criteria (e.g. block access to app when external).
Side Note: If you want to confirm this behaviour yourself, simply use a Win10 machine that is both Domain Joined and AAD Registered, perform a fiddler capture, and compare the sign in experience differences between a IE and Edge (i.e. PRT aware) and Chrome (i.e. not PRT aware)
The Solution/Workaround?
So, you might ask, how do you fix this apparent gap in capability? Does this mean you’re going backwards now? For any enterprise customer of decent size, managing a set of IP address ranges may not be practical or desireable in order to drive MFA (or conditional access) behaviours between internal and external users. The federated user claim method was a simple, low admin, way of solving that problem.
To answer this question, I would actually take a step back and look at the underlying problem that you’re trying to solve. If we remind ourselves of the MFA mantra, the idea is to ensure that the user provides “something they know” (e.g. a secret/password) and “something they have” (e.g. a mobile device) to prove their ‘trustworthiness’.
When we make a decision to allow an MFA bypass for internal users, we are predicating this on the fact that, from a security standpoint, they have met their ‘trustworthiness’ level through a seperate means. This might be through a security access card that lets them into an office location or utilising a corporate laptop that can perform a VPN connection. Both of which ultimately lets them connect to the internal network and thus is what you use as your criteria for granting them the luxury of not having to perform another factor of authentication.
So with that in mind, what you could then do is to also expand that critera to include Domain Joined machines. That is, if a user is utilising a corporate issued device that has been domain joined (and registered to AAD), this can now act as your “something you have” aspect of the MFA mantra to prove your trustworthiness, and so you no longer need to differentiate whether they are actually internal or external anymore.
To achieve this, you’ll need to use Azure AD Conditional Access policies, and modify your Access Grant rules to look something like that below:
You’ll also need to perform the steps outlined in the How to configure automatic registration of Windows domain-joined devices with Azure Active Directory article to ensure the devices properly identify themselves as being domain joined.
Side Note: If you include the Workplace Join packages as outlined above, this approach can also expand to Windows 7 and Windows 8.1 devices.
Side Note 2: You can also include Intune managed mobile devices for your ‘bypass criterias’ if you include the Require device to be marked as compliant critera as well.
Fun Fact: You’ll note that in my image the (preview) reference for ‘require one of the selected controls’ is still there. This is because until recently (approx. May/June 2017), the MFA or domain joined device criteria didn’t acutally work because of the behaviour/order of how the evaluations were being done. When AAD was evaluating the domain joined criteria, if it failed it would immediately block access rather then trying the MFA approach next, thus preventing an ‘or’ scenario. This has now been fixed and I expect the (preview) tag to be removed soon.
Summary
The move to the modern ‘any where, any device’ approach to end user computing means that there is a need to start re-assessing how you approach security. Old world views of security being defined via network boundaries will eventually disappear and instead you’ll need to consider user-and device based contexts to define when to initiate security controls.
With Windows 10’s approach to authentication with AAD, internal and external access is no longer relevant and should not be used for your criteria in driving MFA or conditional access. Instead, use the device based conditions such as ‘device compliance’ or ‘domain join’ as one of your deciding factors.
Glad I came across this post! We are getting ready to do some large orgwide rollouts of Azure MFA and I am running into a problem trying to do exactly this. My assumption was that setting up a single CAP as you’ve done above (require MFA and require AAD joined device both checked, with only one control required) would do what we wanted… Which was to ensure MFA was required on personal computers and bypassed on hybrid AAD joined computers – regardless of location or app. But it doesn’t seem to work… I’ve set myself up this way and my hybrid AAD joined workstation still gets prompted for MFA regularly…
I am experiencing the same issue, have you been able to identify what the problem is yet?
no =(
Hi Wes/Ryan,
When you say you are prompted MFA regularly – is it happening every new browser session, or irregularly? Is it happening to your Office clients as well? Also what build of Win10 are you running?
Regards,
Dave.
it seems to happen on all clients/apps. we run LTSB 2016 (1607).
Hmm in that case it almost seems like your build is not using the PRT as expected or its not registering as ‘domain joined’…. I wonder if that has anything to do with LTSB – though given that it’s 1607 it should still work…
Perhaps it’s worthwhile checking if the device object is being registered as Domain Joined?
https://docs.microsoft.com/en-us/azure/active-directory/device-management-hybrid-azuread-joined-devices-setup#step-5-verify-joined-devices
yes, it’s azure domain joined (confirmed). SSO works seamlessly – it’s just MFA that triggers which I would expect shouldn’t kick in if only one factor is required…
HI,
If my understanding is correct, your problem statement is true only when Windows Hello for Business credentials are used to obtain the PRT in a federated environment. If Username & Password is used to obtain the PRT in a federated environment (ADFS 4.0), the Cloud AP plugin reaches to ADFS and AAD to get the token and internalnetworkclaims are attached to token.
Hi Vinoth,
Correct in that the first time the token is obtained from ADFS it contains the internalnetwork claims, but the key takeaway is that once it has a token, from then onwards there is a cached ‘PRT’ which is then used for all future auth activities to AAD. Thus, if you had MFA rules relying on the ‘insidecorporatenetwork’ claim to bypass MFA, they will stop working as expected.
Regards,
Dave.
I have the same issue as Wes and Vinoth. The device is domain joined (checked with get-msoldevice) and when I ask for hybrid AADjoined OR MFA then MFA is asked even on the domain joined device. I will need to get in touch with Microsoft Support on this. Thanks a lot and keep it up:)
After leaving it a few hours to propagate, the cond access works as expected and MFA is triggered on non-domain joined machines.