Home > ADFS 3.0 > ADFS 3.0: Playing with Authentication

ADFS 3.0: Playing with Authentication

Hello Everyone!

Today, we’ll have a look at the different possibilities offered by ADFS 3.0 in term of authentication.
There were huge improvements compared to the previous versions. Previsously, if you wanted to have something more granular, you had mostly to fall into ADFS pages customization to allow the product to behave according to your specific needs.
As of now, ADFS 3.0 is not requiring IIS anymore, it’s self-hosted and don’t allow you to customize the ASPX pages as you did before. So, unless you have completely redesigned the product in the previous version, you’ll be able to use the new functionalities in order to accomplish what you were doing before and a lot more via the new Powershell cmdlets.

This post will go through 2 main topics:

1) The Home Realm Discovery Page & the usage of different Claims Providers
2) The Primary & Multi-Factor Authentication

The Home Realm Discovery Page

As soon as you play with additional claims providers, the HRD page is displayed to end-users in order for them to make the choice of which Identity Providers they want to use.

There are several reasons why you may want to have additional Identity providers, it can be:

  • Other companies you’re federating with
  • Other public identify providers to allow non-critical/public resources access
  • Other public/on-prem Identity providers to allow strong authentication.
  • etc…

Let’s take an example of an ADFS configuration with 3 Claims Providers, in this case, we have AD for the local authentication, “Azure ACS” as public Idp and “Contoso” as a partner Idp.


As soon as you’ll try to reach one of your relying parties, you’ll get the HRD page displayed as following:


Once a user has selected a specific Claims provider, his selection will be remembered in a specific cookie.

Like the previous version of ADFS, you are able to define whether or not you want to enable that cookie and its associated lifetime.

The great thing here is that instead of modifying the ‘Web.Config’ file on all the concerned ADFS servers in the previous versions, you have now a nice PS cmdlet that allow you to do that in a one shot and for all your servers.

The 2 settings of interest here are HRDCookieEnabled & HRDCookieLifetime

You can get the actual configuration by executing Get-ADFSWebConfig


So, this is nice when you want to leave the end-users the ability to select any Identity Providers they want to use but in some cases, you’ll not want that and for specific relying party, you’ll want to force the end-users to use specific Identity Provider.

For previous version ADFS admins, you know how tricky was that part as there were no out-of-the-box tools to do that except injecting code in the aspx files. It recalls me nice moment’s got it working 😉

Just for posterity (And I’m sure it’ll still help ADFS 2.x Admins): http://adfsauthentication.codeplex.com/

Closing that parenthesis, let’s have a look at what are the new possibilities in ADFS 3.0 in this area:

    1. Avoid having the HRD page displayed to the end-users when connected on the network (Use local AD authentication)

Previously, you had to modify the “HomeRealmDiscovery.aspx.cs” page of all your internal ADFS servers to do that. Now there is just 1 Powershell command that will do it for you and for all your servers:

Set-AdfsProperties -IntranetUseLocalClaimsProvider $true


As a result, internally connected users will never see the HRD page and will get transparently authenticated by AD when accessing relying parties.

  1. Force specific Claims Provider(s) per relying party

This is really a nice feature which is now available out-of-the-box, you can configure any of your relying parties to use specific claims provider(s) – That means that when the end-users access any of your relying parties, if RP are configured to use specific claims providers, only those ones are displayed. In case only 1 is configured, you’re directly redirected to it.

Let’s have a look on how to do that. In this first example, we’ll define 2 claims providers for 1 relying party.

Set-AdfsRelyingPartyTrust -TargetName “MyClaimApp” -ClaimsProviderName @(“Azure ACS”,”Contoso”)


As a result, right-now, we only have “Azure ACS” and “Contoso” available, the AD authentication has been removed from the proposed Claims Providers list:


Now, let’s say that we only want 1 claims provider. We remove “Contoso” from the list

Set-AdfsRelyingPartyTrust -TargetName “MyClaimApp” -ClaimsProviderName @(“Azure ACS”)


As a result, end-user is directly redirected to the wanted Idp. Here Azure ACS.


There is also the possibility to take decision based on user’s domain, let’s see how it works.

For the testing, let’s say that we want our end-users to automatically be redirected to Windows Azure ACS if they want to authenticate with their gmail.com or Hotmail.com addresses.

We’ll make the association between a specific claims provider and domain(s) using the following command:

Set-ADFSClaimsProviderTrust -TargetName “Azure ACS” -OrganizationalAccountSuffix @(“gmail.com”;”hotmail.com”)


As you can see now below, the “Azure ACS” has disappeared from the HRD page as it’ll be matched by the domain the users will enter.

This is particularly useful if you have several federations with partners and don’t want to show the list you’re federating with, you’ll have only ‘other organization’ as a choice.


As soon as we mention an address @gmail.com or @hotmail.com and click on ‘Next’, we’ll be redirected to Azure ACS:



Thanks to this, you can imagine defining your own custom rules, depending on the partners you’re federating with, the security level you want to apply by forcing specific claims providers.

How all those settings are playing together and how the system behaves if you have different rules?

Let’s recall the way HRD is working, as soon as you have selected one of the proposed claims provider and successfully authenticated with, your choice will be remembered by the use of a specific cookie and for a defined period of time.

It means that whatever the rules you’re putting in place, if at some point, you’re reaching a relying party and you’re already authenticated with one of the claims providers proposed for this relying party, you’ll not need to authenticate again.

The HRD page will only be shown if this relying party is using a list of claims providers you’re not already authenticated with.

Authentication levels

Coming along with this new version, we have now 2 new notions in ADFS 3.0:

  • Primary Authentication
  • Multi-Factor Authentication


As you can see, we can now define Authentication Policies in general but also (and that’s the most appreciated one) per relying party.

If you remember, this was pretty limited in the previous version of ADFS where you were basically able to configure Forms/Windows/Certificate authentication but for all the servers internally or externally so no granularity per relying party and no notion of Multi-Factor Authentication

Let’s see what the improvements are 🙂

Primary Authentication

As before ADFS 3.0 you can select: Forms/Windows/Certificate Authentication but you can do that in a single place and for all your servers in a one shot instead of having to customize the “web.config” file separately on each of your ADFS servers.

The difference also here is that you can propose more than 1 authentication method at the same time, so for example, you can define Forms and Certificate Authentication for the Extranet Access so the end-users will have both possibility when accessing the RP.

You can also enable Device Authentication (see my previous post on DRS to enable it here)

The settings present in the default Global Authentication Policy are applied to all your relying parties:


On top of the global authentication policy, you can decide (per relying party) whether you want to re perform authentication or not systematically. This will re-use the primary authentication defined globally.


Here is the external experience when both Forms and Certificate Authentication are selected. As you can see, you have just behind the Username/Password textboxes, the ability to sign-in using a certificate.


Multi-factor Authentication

This is a new feature coming with ADFS 3.0 which allow you to define whether or not you want end-users to provide additional piece of information in order to access a relying party.

As for the primary authentication, you can define a global authentication policy and a specific one for your relying parties.

Let’s have a look at the global authentication policy, you can define:

  • Require MFA for specific users/groups
  • Require MFA for Unregistered/Registered devices (See DRS)
  • Require MFA whether end-users are located inside or outside the company network.
  • Define the additional authentication methods (MFA adapters)


By default, out-of-the-box, you only have Certificate Authentication as additional authentication methods but you can add other MFA adapters, this is really nice stuff as any companies can build their own MFA adapters

The additional ones you can see here are the Windows Azure MFA and a test adapter

I’ll not go into the details on how to install Azure MFA adapter, you can find useful information there:


If you want to have a look on how to build your own adapter, you can check Jen Field’s blog, this is really interesting:



Let’s have a look now at what are the authentication policy per relying party. Let’s decide here that we require MFA for Unregistered devices and for the extranet users.


The first thing that came into your mind is that you have put in place a rule that will trigger MFA if you are on an unregistered device AND on the Extranet but this is not the case. Both statements are separated.

To see exactly what has been done, we can have a look at the relying party details in Powershell.

Under “AdditionalAuthenticationRules” you’ll find the following:


You can see that there are 2 separated claims rules:

c:[Type ==”http://schemas.microsoft.com/2012/01/devicecontext/claims/isregistereduser”,Value == “false”]=> issue(Type =”http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod”,Value = “http://schemas.microsoft.com/claims/multipleauthn”);

c:[Type == “http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork”,Value == “false”] => issue(Type =”http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod”,Value = “http://schemas.microsoft.com/claims/multipleauthn”);

So that means: If the end-users are well on a registered device and located outside the company network, they’ll be anyway prompted for MFA.

So what needs to be done if you want something more granular? So in this case a real AND condition?

First, we’ll define the ‘AND’ rule we need in Powershell:

$newMFARule = ‘[Type == “http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork”, Value== “false”] && [Type ==”http://schemas.microsoft.com/2012/01/devicecontext/claims/isregistereduser”, Value == “false”] => issue(Type =”http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod”, Value = “http://schemas.microsoft.com/claims/multipleauthn”);’


Then we’ll apply that rule to the relying party:


We verify that the setting is now well what we want:


In the UI, you’ll see now that the settings are not available anymore as we have configured a rule which is not available using that UI.


End-user perspective for MFA after succeeding Primary authentication and using a device which is not regirstered with workplace join.


You can see that the 3 MFA adapters you enabled in the Global Authentication Policy for MFA are well proposed as additional authentication method.

Here are some claims output coming from the test user we used here. As you see, the user is not associated with the device. He’s not ‘device registered’ so this is why we got the step-up authentication with MFA. We are also outside corporate network:


If we use a user who has well registered with the device, we don’t receive any step-up authentication being anyway, outside corporate network:


MFA & Security Level

For some obvious reasons, security officers will not consider all those MFA at the same levels of security meaning that they will generally give them a security score and for some relying party will require to have a MFA of a certain score.

That’s great but unfortunately, we’re not able to configure specific MFA providers per relying party. It would be great to have the same functionality as for the claims provider selection we saw earlier in this post (meaning be able to set specific MFA providers per RP) but it’s unfortunately not feasible as of now in the product.

So what can be done?

There is a useful claim which is generated each time you authenticate and contains all the authentication methods you used (whether primary or MFA):


If we add this in the claims output of our test user, let’s see what we get:


We have the following claims:


If you want to know all Authentication methods used by your MFA adpaters, you can use the following command, let’s take the Azure MFA as an example:

(Get-AdfsAuthenticationProvider -Name WindowsAzureMultiFactorAuthentication | Select-Object AuthenticationMethods).AuthenticationMethods


Then, what’s the next step?

As you know that you can get the authentication methods used by the end-users, you can now prepare a simple Issuance Authorization Rule on the Relying Party.

Let’s say that we only want to have the OTP as a valid MFA for a particular relying party.

The issuance authorization rule that you’ll build for that purpose will look like this:

c:[Type == “http://schemas.microsoft.com/claims/authnmethodsreferences”, Value =~ “^(?i)http://schemas\.microsoft\.com/ws/2012/12/authmethod/otp$”] => issue(Type = “http://schemas.microsoft.com/authorization/claims/permit”, Value = “PermitUsersWithClaim”);


We have now put in place the necessary to permit only user authenticating with OTP to access that relying party.

This is fine but just giving an access denied message will not be very user friendly so, and that’s also new with ADFS 3.0, we’ll customize the access denied received for that relying party in order to inform the user why he has been denied access.

To do that, let’s use Powershell, we’ll give a custom error message to the user and let him able to sign-out in order to re-authenticate:

Set-AdfsRelyingPartyWebContent -Name MyClaimApp2 -ErrorPageAuthorizationErrorMessage “<p> You need to authenticate using One Time Password. Click <A href=’https://fs.authnfactor.net/adfs/ls/?wa=wsignout1.0′>here</A&gt; to sign-out.</p>”


Let’s do a test now 🙂

So we use our test user who need to use MFA


We select Multi-Factor Authentication and a call is going to be placed on our phone


We receive an access denied page with the details we provided right-before


We click on the link and are signed out.



That’s all for today, hope you’ll find this interesting!


  1. November 4, 2014 at 4:39 pm

    Is there a way to force ADFS 2.0 or 3.0 to authenticate to multiple claims providers listed in the claims provider trusts? For example, force a user to login to Active Directory and get attributes then redirect the user to go to Oracle “OIF” to also authenticate and get more attributes and then have ADFS combine those attributes and send them to whatever application is the relying party..

    • November 4, 2014 at 7:33 pm

      First of all, whether you are in ADFS 2.0 or 3.0, you can force a specific relying party to use a specific claims provider.
      In order to achieve this:
      1) In ADFS 3.0 there is now a simple PS cmdlet ‘Set-AdfsRelyingPartyTrust -TargetName “YourRelyingParty” –ClaimsProviderName @ (“YourClaimsProvider”)
      2) In ADFS 2.0, this is not available out-of-the-box so you need to customize your Home Realm Discovery Page (HomeRealmDiscovery.aspx.cs) in order to trap the information where your users are going to (meaning which relying party they want to go to) – To do that, you can inject the method available here: http://adfsauthentication.codeplex.com/.
      This method will return you the RP identifier the user is trying to access (whether SAML or WS-Fed) and based on that you can call specific claims provider by calling ‘SelectHomeRealm (“YourClaimsProvider”);’ in Page_Load section
      Do not forget to disabled HRD cookie in this case.

      Knowing that and coming back to your question, you can achieve this via claims rules.
      What is feasible is to force your relying party to authenticate to your Oracle Claims Provider only, then you’ll receive some claims coming from that claims provider.
      Next, you would have a look to the claims you’re receiving from your Oracle CP in order to find any common claims/attributes that you can match with the corresponding AD objects. If it’s the case, then it’s easy, you can use one of the incoming claim as a parameter to query AD for any other wanted attributes.
      If it’s not the case, then you’ll need to build by yourself that relation and this can be achieve either by filling a specific attribute in AD or by using a SQL table (that you can add as an additional attribute store in ADFS) where you’ll specify:
      Attribute xxx in Oracle CP = Attribute yyy in AD

      Hope it helps!

  2. Another ADFS guy
    May 8, 2015 at 9:15 am

    Awesome article… thank you very much!

  3. June 3, 2015 at 10:10 am

    This is a great article – thanks! Do you know why MS do not include the option of mapping a specific Claims Provider for a Non-Claims Relaying Party? The command Set-AdfsNonClaimsAwareRelyingPartyTrust will not take the -ClaimsProviderName parameter. Frustrating because it would be perfect if we could do this.

    • June 3, 2015 at 11:56 am

      Thanks for your comment! Regarding your question, you’re typically using the non-claims-aware relying party to publish on-prem web application using Integrated Authn via WAP and using Kerberos Constrained Delegation. If you’d use another claims provider than AD, you’d not get the necessary to authenticate on the backend side.

      • June 3, 2015 at 4:25 pm

        Hi, thanks for the reply! Actually we are doing something a bit different! I must blog it. We are using Shadow accounts in AD with a 3rd party IDP. Users are authenticated by the 3rd party and their email address is presented as the claim. We transform this into the UPN and it picks up the shadow account from AD (where the UPNs are all client email addresses) and generates a Kerberos Token. We are using WAP as you say. It works really well however we would love to bypass the Home Realm Discovery since they can see the AD login there, plus we may open it to other suppliers in the future. If you ask why use non-claims aware it is because we are using Kerberos delegation all the way back through SharePoint and SSRS to SQL Analysis servers at the back end, which are permissioned to the AD accounts. Although we could make SharePoint claims aware I don’t think we could then have the delegation using Kerberos.

      • June 3, 2015 at 7:48 pm

        Hi Ian, really interesting use-case, thanks for sharing more in depth what you’re currently doing! Indeed, for the time being, you’ll get stuck assigning a specific claims provider to your non-claims-aware app. An other possibility would be to play with “OrganizationalAccountSuffix” but again, you’ll not be able to assign one to Active Directory and this (AD) will remain visible on the HRD page. On the other hand, I have a good news for you, unfortunately, it’ll not help you right-now but the ability to perform what you want to do here is available in the ADFS vNext which is available in Windows Server 2016 Technical Preview 2 so either assigning an OrganizationalAccountSuffix to Active Directory via Set-ADFSClaimsProviderTrust cmdlet or assigning a specific Claims Provider via the Set-AdfsNonClaimsAwareRelyingPartyTrust 🙂

      • November 3, 2015 at 5:27 pm

        Thanks Michelme for excellent article. We have similar situation where we are using 3rd party claim provider to do authentication and KCD to backend applications. Is it somehow possible to make changes on HRD page so that AD option is not visible to users?


      • Adam
        November 4, 2015 at 3:43 pm

        I did look at your comments and i appreciate the help. In the end we decided to build a separate ADFS server specifically for forms based auth.

  4. June 4, 2015 at 8:22 am

    Mitch that is really good news! Thanks for sharing. I am downloading 2016 as I type 🙂

  5. Stephane Gagne
    July 15, 2015 at 3:17 pm

    Thanks for the article. I have a weird question… Can you explain the mechanism of Extranet vs Intranet authentication method as Primary Authentication (Global settings)? I’ve done some testing from different sources and always falling under the Intranet rules…

    • July 16, 2015 at 2:27 pm

      You need to ensure that when you’re doing the extranet testing, you’re going through a WAP server (Proxy).
      This will add specific claims to the request context (like x-ms-proxy) and this will also flag the ‘insidecorporatenetwork’ claim to false, this will let ADFS knows that it’s well an extranet request.
      Hope it helps 🙂

      • stephane gagne
        July 16, 2015 at 2:49 pm

        Thanks Mitch.

        Make more sense now 🙂

  6. Sreerao
    September 9, 2015 at 8:54 pm

    Is it possible to force just the default claims provider (e.g., Active Directory) for all RPs as a default setting (globally), and then have the capability to turn on additional claims providers for specific RPs? It seems that with the current feature, you have to modify all RPs to have just the default one.
    I have over a dozen RPs, and it would be nice to have the global setting feature.

    • September 18, 2015 at 11:48 am

      Hello, sorry for the delayed answer, indeed in the current version, you cannot define this as a global setting. If you use AD only internally, you still have the “IntranetUseLocalClaimsProvider” setting but I agree it’s limitating and will not help you for your external users neither. I did not see such an option in the ADFS vNext but the product is still under development. Mitch

  7. Adam
    October 5, 2015 at 5:50 pm

    Is it possible in ADFS 3.0 to force a specific RP to use forms based auth regardless of client location? Reason is we have a specific SSO that we want the users to have to put their creds in each time they access because of the nature of the information.

    • October 14, 2015 at 7:11 am

      I see one solution but unfortunately with some conditions, if you’re doing SP-Initiated Login and if you have the possibility to configure the SAML request sent to your ADFS server to force the authentication method (using the “AuthnContextClassRef” to form based, typically using the following value “urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport” and finally if you have enabled “forms Authentication” in your global policy (also for the intranet zone) ADFS will satisfy the requested authentication method and then will prompt user to authenticate using FBA (Even internally being logged on a domain-joined PC, using a browser where you experience integrated authentication) On top of this, you can select the option at the relying party level to require credentials each time at sign-in.

      Hope this could help you a bit 🙂


  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: