ADFS MFA with Office 365

We wanted to implement MFA (multi-factor authentication) for our ADFS servers when authenticating to Office 365. If you just want basic “MFA for all users” then the AD FS GUI will allow you to select your MFA provider and enable. I needed a more granular policy:

Only enable MFA if the user is a member of a specific security group AND the user is coming from outside the corporate network AND it is a browser based authentication request

The third part of that policy is in place so that a user can still use activesync or skype for business, since they do not support MFA (or microsoft modern authentication) right now.

Granular ADFS policies are set using “claims”, which can be combined together with “&&” statements. Here are the three claims I needed enabled:

Only enable MFA for members of a security group (use your own group SID in Value == " ")

c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid”, Value == “S-1-2-46-1537777264-XXXXXXXXXXXXX”] &&

Only enable MFA for users outside the corporate network (auth requests that go through the AD FS web proxy)

c1:[Type == “http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork”, Value == “false”] &&

Only enable MFA for browser based requests

c2:[Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path”, Value =~ “(/adfs/ls)|(/adfs/oauth2)”]

Configuration

To apply these claims, first enable the MFA provider using the GUI. Open AD FS, click on “Authentication Policies” and then click “Edit Global Multi-Factor Authentication” on the left-hand side. From there you can select your MFA provider and click “Apply”. After this, you must use powershell. I also used powershell variables to make the process a little cleaner.

First, the $mfarule variable contains all three claims above, joined together with &&:

PS C:\windows\system32> $mfarule='c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value == "S-1-2-46-1537777264-XXXXXXXXXXXXX"] && c1:[Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", Value == "false"] && c2:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value =~ "(/adfs/ls)|(/adfs/oauth2)"] => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value = "http://schemas.microsoft.com/claims/multipleauthn");'

Second, we set the $rpt variable with the name of the Relying Party Trust that needs MFA.

PS C:\windows\system32> $rpt = Get-AdfsRelyingPartyTrust –Name "Microsoft Office 365 Identity Platform"

Last, we use both the variables we defined before and set the MFA rule.

PS C:\windows\system32> Set-AdfsRelyingPartyTrust –TargetRelyingParty $rpt –AdditionalAuthenticationRules $mfarule

And now you are done! The following command reverts the changes made back to default:

PS C:\windows\system32> Set-AdfsRelyingPartyTrust –TargetRelyingParty $rpt –AdditionalAuthenticationRules ''

Additional Commands

The commands above enable MFA just for the Office 365 relying party (so I can have different policies per party). If you would like to enable these settings on a global scale, use this:

PS C:\windows\system32> Set-AdfsAdditionalAuthenticationRule -AdditionalAuthenticationRules $mfarule

And finally, to see all your changes made:

PS C:\windows\system32> Get-AdfsRelyingPartyTrust -Name DisplayNameofRelyingTrust


These blogs were extremely helpful throughout this process:

https://doubledit.co.uk/2015/10/21/adfs-multi-factor-authentication-force-mfa-for-browser-based-access-to-office-365/

http://blog.auth360.net/2014/10/23/mfa-conditional-access-policies-in-ad-fs-2012-r2/

http://blogs.msdn.com/b/ramical/archive/2014/01/30/under-the-hood-tour-on-multi-factor-authentication-in-ad-fs-part-1-policy.aspx

https://technet.microsoft.com/en-us/library/dn479343(v=wps.630).aspx