The Belnet federation is a federation where a lot of Belgian educational or educational related institutions are joined to. I’m currently involved in a POC at one of these institutions. Here’s the situation we started from: they have an Active Directory domain for their employees, and are part of the Belnet federation through a Shibboleth server which is configured as an IDP with their AD. Basically this means that for certain services hosted on the Belnet federation, they can choose to login using their AD credentials through the Shibboleth server.
Now they want to host a service themselves. They would like to provide users outside of their organization access to that service, a SharePoint farm. These users will have an account at one of the institutions federated with Belnet. After some research it came clear to use that we would need an ADFS instance to act as a protocol bridge between SAML and WS-FED. SharePoint does not natively speak SAML. Now the next question: how do we get Belnet to trust our ADFS instance and how do we get our ADFS instance to trust the IDP’s part of the Belnet federation?
These are two different problems and both need to be addressed in order for authentication to succeed. We need to find out how we can let Belnet trust our ADFS instance. But first we zoom into the part where we try to trust the IDP’s in the Belnet federation. This federation has over 20 IDP’s in it and it’s metadata is available at the following URL: Metadata XML file - Official Belnet federation From my first contacts with the people responsible for this federation I heard that it would be hard to get ADFS to “talk” to this federation. They mentioned ADFS does speak SAML, but not all SAML specifications are supported. One of the things that ADFS cannot handle is creating a claims provider trust based upon a metadata file which contains multiple IDPs. And guess what this Belnet metadata file contains…
Some research led me to the concept of federation trusts topologies. Suppose you got two partners who want to expose their Identity Provider so that their users can authenticate at services hosted between partners. In the Microsoft world one typically configures one ADFS instance as a claims provider trust and on the other side the other way round: as a relying party trust. And for the other organization the other way round. And that’s it. But what happens if you want to federate with 3 parties? Now each party has to add two claims provider trusts. And what happens when a new organization joins the federation? Each organization that is already active in the federation has to exchange metadata and add the new organization. As the number of partners in the federation grows you can see that the Microsoft approach seems to scale badly for this…
Now after reading up a bit on this subject I learned that there are two types of topologies: full mesh and proxy based. In the proxy approach each party federates with the proxy and the proxy remains in the middle for authentication requests. In the full mesh topology each party federates with each party. As I explained above, a full mesh approach scales bad. The Belnet setup is mostly based upon Shibboleth and each Shibboleth server gets updated automatically whenever an additional IDP or SP is added to the federation. So Belnet is only responsible for distributing the federation partner information to each member. So I came up with the following idea: If I were to take the Belnet XML file and chop it into multiple IDP XML files, I could add those one by one to the ADFS configuration. I got this idea here: Technet (Incommon Federation): Use FEMMA to import IDPs
Here’s a schematic view of the Federation Metadata exchanges. It might makes things a bit more clear. On the schema you’ll see the Shibboleth server, but in fact, for the SharePoint/ADFS instance it’s irrelevant.
Adding Belnet IDP’s to ADFS
Search the Belnet federation XML file for something recognizable like part of the DNS domain: vub.ac.be, or (part of) the name of the IDP: Brussel Once you got the good entry we need everything from this IDP that’s between the <EntityDescriptor> tags. So you should have something like this:
Copy this to a separate file and save it as FederationMetadata_VUB.xml
Now go to the ADFS management console and add a claims provider trust.
When asked, provide the XML file we just created. When you’re done change the Signature hash algorithm. You can find this on the advanced trust. This might differ from trust to trust and you can try without changing, but if your authentication results in an error, check your ADFS event logs and if necessary change this setting.
Authentication Failed. The token used to authenticate the user is signed using a weaker signature algorithm than expected.
And that’s it. Repeat for any other IDP’s you care about. Depending on the number of IDP’s this is a task you’d want to script or not. The InCommon federation guide contains a script written in Python which provides similar functionality.
Adding your ADFS as SP to the Belnet Federation
Now the first part seemed easy. We had to do some cutting and pasting, but for a smaller amount of IDP’s this seems doable. Now we have to ensure all involved IDP’s trust our ADFS server. In the worst case we have to contact them one by one and exchange information. But that would mean we’re not benefitting the Belnet federation. Our goal is to have our ADFS trusted by Belnet and that will ensure all Belnet partners trust our ADFS instance. This would ensure we only have to exchange information with one party and thus simplifying this process a lot!
First we need the Federation Metadata from the ADFS instance: https://sts.contoso.com/FederationMetadata/2007-06/FederationMetadata.xml
Then we need to edit a bit so that the Belnet application that manages the metadata is capable of parsing the file we give it. Therefore we’ll remove the blocks we don’t need or that tooling at Belnet is not compatible with:
- Signature block: <signature>…</signature>
- WS-FED stuff: <RoleDescriptor xsi:type="fed:ApplicationServiceType … </RoleDescriptor>
- Some more WS-FED stuff: <RoleDescriptor xsi:type="fed:SecurityTokenServiceType" … </RoleDescriptor>
- SAML IDP stuff, not necessary as we’re playing SP: <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> … </IDPSSODescriptor>
We also need to add some contact information:
There should be a block present that looks like this: <ContactPerson contactType="support"/>
Replace it with:
Now you’re ready to upload your modified metadata at Belnet: https://idpcustomer.belnet.be/idp/Authn/UserPassword
After some time you’ll be able to logon using the IDP’s you configured. Pretty cool eh! Authentication will rely on the trusts shown below:
Scoping: once you trust several IDP’s like this, you might be interested in a way to limit the users to the ones your organization works with. The customer I implemented this has an overview of all users in their Active Directory. So we allow the user to log on at their IDP, but we have ADFS authorization rules that only issue a permit claim when we find the user as an enabled AD user in the customer AD. These user are there for legacy reasons and can now be seen as some form of ghost accounts.
Certificates: the manual nature of the above procedure also means you have to keep the certificates up to date manually! If the IDP starts using an other certificate you have to update that IDP specific information. If you change your certificates on the ADFS instance you have to contact Belnet again and have your metadata updated. Luckily most IDP’s in the Belnet federation have expiration dates far away in the future. But not all of them. Definitely a point of attention.
Just drop a comment if you want more information or if you got some feedback.