***<font face="Arial, sans-serif">A working ADFS 2012R2 implementation.</font>**_<font face="Arial, sans-serif">Apologies but this isn’t something I’ve blogged about yet (I will, soon). For now, there are plenty of fantastic articles on setting up ADFS out there but when you do it, make sure you’re setting up ADFS 2012R2 (It’s on Windows Server 2012R2 of course). Why am I telling you to set it up on Windows Server 2012R2? Simple, [Alternate Login ID](https://technet.microsoft.com/en-us/library/dn659436.aspx).</font>_
***<font face="Arial, sans-serif">Access to a Linux box with an updated version of OpenSSL.</font>**_<font face="Arial, sans-serif">OK, so strictly you don’t need a Linux box – it’s just easier if you have access to one. We need to generate a certificate and key for token signing purposes and fiddling with installations of OpenSSL on Windows isn’t something I want to document. Spin one up in Azure and bin it once you’re done with it!</font>_
# <a name="more-1534"></a><font face="Arial, sans-serif">Configure SimpleSAMLphp to use ADFS 2012R2 as an IdP</font>
<fontface="Arial, sans-serif">The first thing to do is configure SimpleSAMLphp with our ADFS server’s federation metadata. To do this, we must download the <fontstyle="font-size: 10pt"size="2">FederationMetadata.xml</font> file from our ADFS server and use SimpleSAMLphp to convert it in to a format that it can understand.</font>
1.<fontface="Arial, sans-serif">Firstly, I know my Federation Service is located at [https://fs.transishun.co.uk/](https://fs.transishun.co.uk/) but where’s the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">FederationMetadata.xml</font></font><fontface="Arial, sans-serif">file? To get the location of the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">FederationMetadata.xml</font></font><fontface="Arial, sans-serif">file: on your ADFS server open the ADFS Management console, expand</font>**<font face="Arial, sans-serif">Service</font>**<fontface="Arial, sans-serif">and select the</font>**<font face="Arial, sans-serif">Endpoints</font>**<fontface="Arial, sans-serif">node. The Metadata section shows us that the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">FederationMetadata.xml</font></font><fontface="Arial, sans-serif">file is located at</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">/FederationMetadata/2007-06/FederationMetadata.xml</font></font><fontface="Arial, sans-serif">.
This is actually the same location for all ADFS services but I wanted to show you where it was from.
2.<fontface="Arial, sans-serif">Open a browser and navigate to the <fontstyle="font-size: 10pt"size="2">FederationMetadata.xml</font> location: <fontstyle="font-size: 10pt"size="2">https://fs.transishun.co.uk/FederationMetadata/2007-06/FederationMetadata.xml</font> where you’ll be prompted to save the file to disk.
4.<fontface="Arial, sans-serif">Browse to our web application’s installation of SimpleSAMLphp. Navigate to the Federation tab and click</font>**<fontface="Arial, sans-serif">XML to simpleSAMLphp metadata converter
</font>****_<font face="Arial, sans-serif">NB: If you have no clue what I’m talking about, it would be a good idea to read through the two posts preceding this one where I explain how to install and configure SimpleSAMLphp</font>_**<fontface="Arial, sans-serif"></font>
5.<fontface="Arial, sans-serif">Paste the contents of the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">FederationMetadata.xml</font></font><fontface="Arial, sans-serif">file in to the</font>**<font face="Arial, sans-serif">XML metadata</font>**<fontface="Arial, sans-serif">field and click the</font>**<font face="Arial, sans-serif">Parse</font>**<fontface="Arial, sans-serif">button.
6.<fontface="Arial, sans-serif">The page will return two sets of data. For our purposes, the first:</font>**<font face="Arial, sans-serif">saml20-sp-remote</font>**<fontface="Arial, sans-serif">can be ignored since we are not using SimpleSAMLphp as an identity provider, that’s ADFS’ job. Scroll to</font>**<font face="Arial, sans-serif">saml20-idp-remote</font>**<fontface="Arial, sans-serif">and copy the contents of this field to the clipboard.
7.<fontface="Arial, sans-serif">Browse to the installation of SimpleSAMLphp on the IIS server and open the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">metadata</font></font><fontface="Arial, sans-serif">folder.</font>**_<font face="Arial, sans-serif">NB: Don’t know what I’m talking about or where this is? Please read the two posts preceding this one!</font>_**<fontface="Arial, sans-serif"></font>
8.<fontface="Arial, sans-serif">Open the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">saml20-idp-remote.php</font></font><fontface="Arial, sans-serif">file in your favourite text editor.</font>_<font face="Arial, sans-serif">Note: Did you notice the pattern? We copied the data from the</font> __**<font face="Arial, sans-serif">saml20-idp-remote</font>**__ <font face="Arial, sans-serif">field of the converted metadata page and that is now going to be copied in to the PHP file of the same name.</font>_<fontface="Arial, sans-serif"></font>
9.<fontface="Arial, sans-serif">Paste the converted metadata at the bottom of the file then save it.
3.<fontface="Arial, sans-serif">I’m not going to repeat much of what I wrote in the post preceding this one where I added a Service Provider for Azure AD. Here, we will create a service provider configuration that uses our ADFS server. There are some differences in the configuration between Azure AD and ADFS 2012R2. The name of your SP is your choice, mine is called <fontstyle="font-size: 10pt"size="2">transishun-sp</font>.</font>
<fontcolor="#0000ff"><fontface="Arial, sans-serif">// The entity ID of this SP.</font></font>
<fontcolor="#0000ff"><fontface="Arial, sans-serif">// Can be NULL/unset, in which case an entity ID is generated based on the metadata URL.</font></font>
<fontcolor="#0000ff"><fontface="Arial, sans-serif">// ADFS 2012R2 requires signing of the logout - the others are optional (may be overhead you don't want.)</font></font>
<fontcolor="#0000ff"><fontface="Arial, sans-serif">// We now need a certificate and key. The following command (executed on Linux usually)</font></font>
<fontcolor="#0000ff"><fontface="Arial, sans-serif">// creates a self-signed cert and key, using SHA256, valid for 2 years.</font></font>
2.<fontface="Arial, sans-serif">You will notice that the SP code defines that we must <fontstyle="font-size: 10pt"size="2">sign.logout</font>, <fontstyle="font-size: 10pt"size="2">redirect.sign</font> and <fontstyle="font-size: 10pt"size="2">assertion.encryption</font>. All of these declarations mean we need a certificate and key to sign and encrypt these communications. We’ll create the certificate and key in the next section.</font>
3.<fontface="Arial, sans-serif">The final declaration enforces the use of SHA-256 which is best practice.</font>
# <font face="Arial, sans-serif">Creating a certificate and key file for signing and encryption</font>
<fontface="Arial, sans-serif">I mentioned in the requirements that you would need a Linux machine. Again, if you need one, just spin one up on Azure, I did.</font>
3.<fontface="Arial, sans-serif">If you recall from the SP definition code at the end of previous section, I provided an example command for generating a two year certificate and key:
</font></font>_<font face="Arial, sans-serif">I extrapolated this from [the documentation on the SimpleSAMLphp website](https://simplesamlphp.org/docs/1.13/simplesamlphp-sp) in section 1.1\. If you’re using this in a production environment, generate a key and cert that will last. The SimpleSAMLphp documentation suggests 10 years.</font>_
4.<fontface="Arial, sans-serif">Run the command to create the key and certificate. You will be asked a number of questions, answer these however you like, this cert and key is only used for signing and encrypting on the SP. My run through is shown below.
5.<fontface="Arial, sans-serif">Now you need to download the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">my.key</font></font><fontface="Arial, sans-serif">and</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">my.pem</font></font><fontface="Arial, sans-serif">files. There’s a number of ways but since they’re just text, I usually just</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">cat</font></font><fontface="Arial, sans-serif">them to screen and copy/paste from the Putty console in to a file on my local machine.
</font>**_<font face="Arial, sans-serif">NB: Don’t get too excited, this is an example key, I don’t use this one myself.</font>_**
6.<fontface="Arial, sans-serif">Navigate to the SimpleSAMLphp installation folder and create a folder called <fontstyle="font-size: 10pt"size="2">cert</font>.
7.<fontface="Arial, sans-serif">Copy the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">my.key</font></font><fontface="Arial, sans-serif">and</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">my.pem</font></font><fontface="Arial, sans-serif">files in to the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">cert</font></font><fontface="Arial, sans-serif">folder. These are the two files that we declared when we created the Service Provider configuration in</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">authsources.php</font></font><fontface="Arial, sans-serif">. The</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">cert</font></font><fontface="Arial, sans-serif">folder is the default location for certs and keys in SimpleSAMLphp as mentioned in [the documentation](https://simplesamlphp.org/docs/1.13/simplesamlphp-sp).
# <font face="Arial, sans-serif">Create the Relying Party Trust in ADFS 2012R2</font>
<fontface="Arial, sans-serif">Now that the Service Provider configuration is complete, SimpleSAMLphp creates the SAML 2.0 SP metadata that we can use to import in to ADFS.</font>
1.<aname="crayon-5f7fe0cd8ab70580383406"></a><aname="crayon-5f7fe0cd8ab72428592771"></a><fontface="Arial, sans-serif">Navigate to the web application’s</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">/simplesaml</font></font><fontface="Arial, sans-serif">application and click the</font>**<font face="Arial, sans-serif">Federation</font>**<fontface="Arial, sans-serif">tab. As you can see, our previous</font>**<font face="Arial, sans-serif">default-sp</font>**<fontface="Arial, sans-serif">configuration (the one we configured for use with Azure AD) is here, but now so is the one I’ve called</font>**<font face="Arial, sans-serif">transishun-sp</font>**<fontface="Arial, sans-serif">. If you’re wondering where the heck that URL came from, it’s because we left the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 9pt"size="2">entityID</font></font><fontface="Arial, sans-serif">value</font><fontface="Arial, sans-serif"><fontstyle="font-size: 9pt"size="2">null</font></font><fontface="Arial, sans-serif"> when we specified the SP configuration.</font>
<fontcolor="#0000ff"><fontface="Arial, sans-serif">// The entity ID of this SP.</font></font>
<fontcolor="#0000ff"><fontface="Arial, sans-serif">// Can be NULL/unset, in which case an entity ID is generated based on the metadata URL.</font></font>
8.<fontface="Arial, sans-serif">If you wish, click the</font>**<font face="Arial, sans-serif">Show metadata</font>**<fontface="Arial, sans-serif">link to see the metadata but before you do, copy the</font>**<font face="Arial, sans-serif">Entity ID</font>**<fontface="Arial, sans-serif">: url. We need to give this to ADFS when we configure the Relying Party Trust.
12.<fontface="Arial, sans-serif">Next your way through the wizard until you reach the</font>**<font face="Arial, sans-serif">Ready To Add</font>**<fontface="Arial, sans-serif">Trust page. Here you’ll want to review the numerous tabs – check the</font>**<font face="Arial, sans-serif">Encryption</font>**<fontface="Arial, sans-serif">and</font>**<font face="Arial, sans-serif">Signature</font>**<fontface="Arial, sans-serif">tabs have certificates associated with them. Even if they don’t and you’ve not completed the previous section to create the certificates, the RPT can be updated whenever you like.
14.<fontface="Arial, sans-serif">Select the</font>**<font face="Arial, sans-serif">Relying Party Trust</font>**<fontface="Arial, sans-serif">we’ve just added and then click</font>**<font face="Arial, sans-serif">Edit Claim Rules…</font>**<fontface="Arial, sans-serif"></font>
15.<fontface="Arial, sans-serif">Add an</font>**<font face="Arial, sans-serif">Issuance Transform Rule</font>**<fontface="Arial, sans-serif">based on the</font>**<font face="Arial, sans-serif">Send LDAP Attributes as Claims</font>**<fontface="Arial, sans-serif">template. Select at least</font>**<font face="Arial, sans-serif">UPN</font>**<fontface="Arial, sans-serif">, whatever else you choose here is your choice but add another such as</font>**<font face="Arial, sans-serif">mail</font>**<fontface="Arial, sans-serif">or</font>**<font face="Arial, sans-serif">uid</font>**<fontface="Arial, sans-serif">.
16.<fontface="Arial, sans-serif">Add another Issuance Transform Rule but this time based on the</font>**<font face="Arial, sans-serif">Transform an Incoming Claim</font>**<fontface="Arial, sans-serif">template. This one is important and is required to allow SimpleSAMLphp to talk with ADFS.
<fontface="Arial, sans-serif">Now that we have configured SimpleSAMLphp as the service provider, ADFS as the IdP, exchanged metadata between the two and configured some basic claims rules. We are now able to test authentication.</font>
1.<fontface="Arial, sans-serif">Navigate to the simplesaml web application for our site https://sso.lewisroberts.com/simplesaml then select the</font>**<font face="Arial, sans-serif">Authentication</font>**<fontface="Arial, sans-serif">tab and click</font>**<font face="Arial, sans-serif">Test configured authentication sources</font>**<fontface="Arial, sans-serif">.
3.<fontface="Arial, sans-serif">You will be immediately sent off to the ADFS server (or Web Application Proxy depending on how your ADFS farm is configured). Enter your user ID in the format “domain\user” or “user@domain”.
</font>**<font face="Arial, sans-serif">NB</font>**<fontface="Arial, sans-serif">: Now, I’ve cheated slightly, I have [enabled Alternate Login ID](https://technet.microsoft.com/en-us/library/dn659436.aspx) so I can sign in with my email address. If you see the article I’ve linked to, Microsoft</font>**<font face="Arial, sans-serif">strongly</font>**<fontface="Arial, sans-serif">recommend using the mail attribute for sign in. As they say;</font>_<font face="Arial, sans-serif"><font style="font-size: 10pt" size="2">One of the benefits of this feature is that it enables you to adopt SaaS providers, such as Office 365 with AAD without modifying your on-premise UPNs. It also enables you to support line-of-business service applications with consumer-provisioned identities.</font></font>_<fontface="Arial, sans-serif"></font>
4.<fontface="Arial, sans-serif">Once signed in, you’ll be bounced back to SimpleSAMLphp and shown your claims. If it all went a bit wobbly, double-check everything and then check the Event Viewer for hints as to what could have gone wrong.
5.<fontface="Arial, sans-serif">Click</font>**<font face="Arial, sans-serif">Logout</font>**<fontface="Arial, sans-serif">to test this works as expected – this is where the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">sign.logout</font></font><fontface="Arial, sans-serif">declaration in the Service Provider configuration becomes relevant. ADFS</font> _<fontface="Arial, sans-serif">requires</font>_ <fontface="Arial, sans-serif">the logout to be signed.
6.<fontface="Arial, sans-serif">Let’s add another claim using the</font>**<font face="Arial, sans-serif">Send Group Membership as a Claim</font>**<fontface="Arial, sans-serif">template just to get a little more understanding of what’s happening.
# <font face="Arial, sans-serif">What about our custom PHP application?</font>
<fontface="Arial, sans-serif">Good job you asked, I nearly forgot.</font>
<fontface="Arial, sans-serif">In the previous blog post, I provided some code that I took from the SimpleSAMLphp website. On line 3 of that code when we created a new object, we specified the service provider we wanted to use. It looked like this:</font>
<fontface="Arial, sans-serif">Not to be too cheeky but basically, we would simply change the service provider to, you guessed it, <fontstyle="font-size: 10pt"size="2">transishun-sp</font>. After doing so, the whole file looks like this:</font>
<fontface="Arial, sans-serif">After changing that, you can test your application and instead of being sent off to Azure AD for authentication, you’ll be sent to the federation service where, after logging on and being sent back to your application, you’ll see something like this – obviously changing depending on the claims you configured.</font>
<fontface="Arial, sans-serif">Hang on, I noticed in the</font>**<font face="Arial, sans-serif">index.php</font>**<fontface="Arial, sans-serif">file that the</font><fontface="Arial, sans-serif"><fontstyle="font-size: 10pt"size="2">logout</font></font><fontface="Arial, sans-serif">link is different than the preceding post’s example. You’re right, it is – why? Well, if you left that Logout link in place, you will indeed be logged out but then you’ll be sent straight back to the application which will need you to log back in again and you’ll be sent off to sign in – not a great user experience.</font>
<aname="crayon-5f7fe0cd8ab7a096290175"></a><fontface="Arial, sans-serif">To overcome this, we can send our user to a different page. It</font> _<fontface="Arial, sans-serif">can</font>_ <font face="Arial, sans-serif">be done using the</font> <font face="Arial, sans-serif"><font style="font-size: 9pt" size="2">getLogoutURL()</font></font><font face="Arial, sans-serif">function but if we wish to be certain the user was logged out, as per [the SimpleSAMLphp documentation section 5.3](https://simplesamlphp.org/docs/1.13/simplesamlphp-sp-api), I would create two files:</font> <font face="Arial, sans-serif"><font style="font-size: 10pt" size="2">logout.php</font></font> <font face="Arial, sans-serif">and</font> <font face="Arial, sans-serif"><font style="font-size: 10pt" size="2">logged_out.php</font></font><fontface="Arial, sans-serif">with the following contents. What each file does should be pretty clear.</font>
<fontcolor="#0000ff"><fontface="Arial, sans-serif">// Logout failed. Tell the user to close the browser.</font></font>
<fontcolor="#0000ff"><fontface="Arial, sans-serif">echo("We were unable to log you out of all your sessions. To be completely sure that you are logged out, you need to close your web browser.");</font></font>
<fontface="Arial, sans-serif">Well, that about wraps it up for another large post but hopefully there’s some useful information in there for you. If you’ve found the article helpful, you can say a quick thanks by clicking an advert. Don’t forget to read the two posts preceding this one to discover why I went down this rabbit hole and decided to take you all with me.</font>