Connect two AD FS federation servers

logo-adfsThis post contains three configuration tips I hope will help you configure several Active Directory Federation Services 3.0 (ADFS) servers to communicate with each other and allow your application relying parties (RP) to communicate through one ADFS server to request claims from a second ADFS server. AFDS works like a charm — but the documentation (especially for ADFS 3.0) is severely lacking. Microsoft offers only basic configuration doc spread all over the ‘Net. There seems to be little practical info available, leaving architects to piece everything together via trial and error. This post won’t replace some serious Google searching on your part but it might help if your objectives are similar to mine.

Let’s start with a serious (and, as of this writing) unfixed bug in ADFS 3.0 on Windows Server 2012 R2. If you run ADFS on your domain controller (as I did in a test environment in the cloud) and you select a group Managed Service Account (gMSA) for the ADFS service credentials, you will not be able to login to the server after a restart. This is, of course, a catastrophe when you run in the cloud (in our case, AWS).

I found a solution here. Set up a normal userid with Domain Admin privileges to use with ADFS. And set the Key Distribution service to start automatically at boot. Problem solved.

Update: February 27, 2015: Wrong, wrong, wrong! There is a problem, but I misunderstood it. The issue is the ADFS service must get a key from the Key Distribution Service which must, of course, start before the ADFS service. Yet ADFS on Windows Server 2012 R2 ships without the KdsSvc dependency included when on a domain controller.

Here’s the right way to fix ADFS running on a domain controller:
sc config adfssrv depend=HTTP/KdsSvc
You can do a before/after with this command:
sc qc adfssrv

Remember: you have do this before you reboot your server. If you don’t and it’s a cloud server, you’re dead. Microsoft really, really needs to fix this.

Update: October, 2016: If you install AD FS in Windows Server 2016 on a domain controller, you must still make sure you add the dependency on the key service after you configure AD FS on the domain controller and before you reboot the server. This screen shot shows what you should see after you’ve set up the dependency.

The AD FS service on a Windows Server 2016 domain controller requires a dependency on KdsSvc
The AD FS service on a Windows Server 2016 domain controller requires a dependency on KdsSvc (click to enlarge)

Now for the good stuff: how can we make one ADFS server a hub to serve our applications and users by supplying both local credentials and credentials from a remote ADFS server? Consider the following design.

ADFS to ADFS trusts
ADFS to ADFS trusts (click to enlarge)

Why would one ever do this? There are a couple of reasons. Suppose your ADFS server needs to act as a hub to permit authorization from multiple federated partners. By pointing users and claims-aware applications to your hub, relying parties can easily authenticate with different claims providers as needed. Another good reason is to allow your developers to test against your ADFS server without burdening the federation partner’s server(s).

Here are the most important considerations I discovered.

  • The trust to your server from the remote ADFS server is a relying party trust
  • The trust from your server to the remote ADFS server is a claims provider trust
  • What makes it all hang together are pass-through claims rules on both trusts. 

It’s easy to connect the two servers; just give your remote admin the metadata URL for your ADFS server. A more subtle requirement is that the two trusts must be identical in all respects. That means that when you are talking with the admin of the remote ADFS server, you need to ensure that he or she enters all the claims as he or she defines the relying party trust to you precisely as your relying party trust application expects them.

This screenshot shows an example of a single pass-through claims rule for a standard claim, “Surname”. In a two-server local and remote ADFS configuration, this claim is entered three times. Once is in the remote RP ADFS server’s claim rules for this trust (this is obviously done by the admin at the remote server). Second, you must enter the identical claim in your local server’s claims provider trust defining the remote ADFS server. And third, it is entered in the RP trust for your application. When you enter this rule on the claims provider trust, you’ll get a warning about security that’s safe to ignore.

Pass-through claims rules in ADFS 3.0 (click to enlarge)
Pass-through claims rules in ADFS 3.0 (click to enlarge)

My third tip is something I could not find clear, explicit documentation on how to do. How does one allow both local claims and remote claims to be provided to the local relying party application? It’s simple: just enter the claims rules for your local ADFS server in the same way and place as you did for the remote pass-through claims. See below for a screenshot showing both  claims originating in the local ADFS server and claims coming for this relying party application from the remote AFDS server.

Pass-through and local claims in the same relying party (click to enlarge)
Pass-through and local claims in the same relying party (click to enlarge)

Once again, you must make certain that the claims rules for the remote connection match in every respect all the way through from the remote ADFS server through the claims provider trust on your local server and ending up in your local relying party application. It’s complex but if you think about it, it all makes sense.

Here’s a bonus tip that requires PowerShell. (You can leave a quarter in the slot.) I find it more convenient to force Home Realm Discovery every time our app or users hit our server. If you go with the defaults, ADFS stores a cookie for 30 days after initial HRD. If you are testing an app or a user needs to switch realms, they have to clear their cookies — an inconvenience. This self-documenting script forces HRD on every request.

Import-Module adfs
Set-AdfsWebConfig -HRDCookieEnabled $false # Uncomment to require HRD on every login
#Set-AdfsWebConfig -HRDCookieLifetime 30 -HRDCookieEnabled $true # Uncomment to set to default

Update July 26, 2016: See this post on how to use an ADFS PowerShell cmdlet to avoid a nasty surprise when you attempt to copy-and-paste token-signing and other ADFS certificates.


Posted

in

, , ,

by

Comments

11 responses to “Connect two AD FS federation servers”

  1. Jason Avatar
    Jason

    First of all, thank you. this is a brilliant solution. Now the obvious “but”…

     

    I have it up and working except… when I try using any user from the external on the internal it tells me bad username and password. I can see in the logs that it’s actively reaching out to the relying party but it’s getting an error that I’ll just paste a smidgen of here…

    Encountered error during federation passive request.

    Additional Data

    Protocol Name:

    Saml

    Relying Party:

    http://test.whatever.com/adfs/services/trust

    Microsoft.IdentityServer.AuthenticationFailedException: [email protected]-The user name or password is incorrect —> System.IdentityModel.Tokens.SecurityTokenValidationException: [email protected]—> System.ComponentModel.Win32Exception: The user name or password is incorrect.

    I of course go over to the relying part and user the exact same credential pair without issues.

    I’m “guessing”  that there’s something going on with maybe the way it’s passing that information to the relying party and the relying party not using the correct means of deciphering what it’s been given.

    Any ideas? I’ve looked around a bit in the endpoints but I’ll be honest, I haven’t the foggiest clue as to whether or not a particular non default endpoint should be enabled and if so then added to the identifiers for the trust.

    Anyway, I know you don’t support us guys for a living or what have you but if that just screams “oh yeah, I totally know what that is!” then please share 🙂

     

    Cheers!

     

     

    1. Alex Neihaus Avatar
      Alex Neihaus

      Sorry — just saw your post in the spam folder.

      My best recommendation is: take the error message at face value. It says you have an authentication issue. That _may_ be because your RP trust is incorrect (which is an endpoint issue) — OR it could be that you haven’t selected the correct directory in the trust and maybe you haven’t written the pass-thru rules correctly.

      Good luck.

  2. Sam Avatar
    Sam

    Hi Alex,

    I followed the instructions in your article to set up a federation trust between two ADFS servers, but I’m having a problem. Your architecture diagram exactly depicts my setup in a lab. Here’s some details of my setup. I use:

    ADFS 2 (2008R2) for my ADFS Server A (Claims Provider/external) and ADFS 3 (2012R2) for my ADFS Server B (internal)
    SharePoint 2010 as a claim-aware web application requesting the authentication
    UPN as a sole claim rule to make the configuration as simple as possible
    Certificate as the authentication method as users need to login with their smart cards (via Primary Authentication; MFA is not used)

    The problem I’m having is when I select ADFS Server A from the Home Realm Discovery page (on ADFS Server B), it does not launch the certification selection window even though HRD redirects the page to ADFS Server A and shows “Select a certificate that you want to use for authentication. If you cancel the operation, please close your browser and try again”. It doesn’t give any errors anywhere either (not even in ADFS tracing logs).

    Any idea what might be causing this? Any info would be appreciated!

    1. Alex Neihaus Avatar
      Alex Neihaus

      Could it be that the authentication method on server b does not have passthrough rules for UPN from server a?

      1. Sam Avatar
        Sam

        I confirmed that Server B (local ADFS) has the passthru rule followed by the local LDAP Attribute rule in its Relying Party Trusts. Also it has the same passthru rule (and no other rules) on its Claims Provider Trusts.

        On Server A (remote ADFS), I also have the passthru rule in its Relying Party Trust and its Claims Provider Trusts just shows Active Directory.

        Any other thoughts?

        1. Alex Neihaus Avatar
          Alex Neihaus

          First, you should understand I don’t do technical support for free on this blog. As always YMMV on anything you read or see here. Second, when I get stuck in a Windows issue, I step back and try to take the error message at face value. Your say your error message is about certificates, so have you made sure that the cert for the external claims provider is correct in AD FS? Have you checked on when the metadata was last refreshed in the AD FS snap-in? You might also want to take a look at a post I recently wrote about the danger of copying and pasting certificates from the Windows certifcate snap-in.

          1. Sam Avatar
            Sam

            Thanks for your inputs. I’m not getting any error messages and that’s what drives me crazy. The ADFS console shows the metadata was last refreshed today and it’s not the cert copying/pasting issue…

  3. Mark Avatar
    Mark

    Hi Alex,

    as far as I understood I checked all the settings you mentioned.

    I assembled some more detailed screenshots here on imgur. Maybe you could a look?

    Thanks a lot.

    Mark

    1. Alex Neihaus Avatar
      Alex Neihaus

      Well, I think you are seeing two claims provider trusts because there are two claims providers. This shouldn’t be an issue. If you want only the “remote” one, remove the local one from the AD FS login screen.

  4. Mark Avatar
    Mark

    Hi, Alex

    first of all thanks for sharing your thoughts. It think it was really valuable input for me.

    I tried to build an AD FS to AD FS scenario with SharePoint and I’m kind of stuck now.

    I started with one Domain-Forest where AD FS and SharePoint are seated. I manged to create an Authentication Provider in SP to authenticate against AD FS with the local domain. That worked so far.

    I mainly used the claims described here: https://technet.microsoft.com/de-de/library/hh305235.aspx

    Now I wanted to add a second external domain with AD FS as an Claims Provider Trust to my existing AD FS and followed your tipps here.

    The odd thing is now when I see the AD FS website to which I’m redirected, I can choose between local and external domain claims provider trusts before I get to the login form. Choosing the internal and loggin in with the credentials of an external user fails. Choosing external fails, because it redirects to the external AD FS webform and after this the claim would fail, because SharePoint does not know about the second AD FS server.

    Should the authentication against the external AD FS not be transparent for the SharePoint Authentication Provider? Or do I really have to add another authentication provider in SharePoint for the other AD FS server?

    That would be bogus I guess, because then it would not be the two AD FS servers handling out the claims like your chart at the beginning shows.

    Would be great if you could shed some light upon this.

    Maybe we could also get in touch via email?

    Thanks a lot.

    1. Alex Neihaus Avatar
      Alex Neihaus

      Thanks for the feedback, Mark.

      Are you sure you:
      1) added the “remote” SharePoint Server as a Claims Provider in the “local” AD FS server servicing the local SharePoint as a relying party?
      2) added pass-though claims rules for the local AD FS server that EXACTLY match the claims coming from the remote AD FS server?

      It’s confusing, but the RP trust for the “local” AD FS server should have two sets of rules. One for when the claims are coming from “this” Active Directory and a set (since they are entered one at a time) for the claims coming from the “remote” AD.

Leave a Reply

Your email address will not be published. Required fields are marked *