# Single Sign-on to Azure AD using SimpleSAMLphp

by [Lewis](https://www.lewisroberts.com/author/ljr/) · Sat 5th September, 2015

In my last mammoth post, I posted an update/re-write to an article originally written on the Azure website that used some libraries provided by Microsoft to enable custom PHP applications to sign-on to Azure AD using WS-Federation. In that post I described a method for installing and configuring SimpleSAMLphp to IIS that enables it to be used by any number of sites on the same server, all that’s required is to add a simple Virtual Directory to each site. If you want to configure SimpleSAMLphp on IIS, check that post out.

The intention with this post is to do away with Microsoft’s libraries altogether and use only SimpleSAMLphp in a more integrated way. The purpose is to avoid having to re-write a lot of functionality already provided by SimpleSAMLphp that’s likely to be missing from Microsoft’s libraries, and of course open up access to SimpleSAMLphp’s documented API.

I will assume you have configured SimpleSAMLphp already using the method documented in the last post. In order to proceed in this post, you also need to have configured an application within Azure Active Directory. Again, you can find instructions for that included in the previous post.

The largest difference with this post is, as I mentioned, better integration with SimpleSAMLphp – as such, there’s more configuration to complete within SimpleSAMLphp than there was in the previous post.

*   We’ll import federation data from our Azure application in to SimpleSAMLphp.

*   We’ll configure SimpleSAMLphp as a Service Provider.

*   We’ll create a little code to get us authenticating.

# <a name="more-1489"></a>Pre-requisites

1.  As mentioned, we need SimpleSAMLphp set up on the server as per my previous post. In _this_ post, I’ve created a new website called <font face="Courier New"><font style="font-size: 10pt" size="2">sso.lewisroberts.com</font></font> and configured the Virtual Directory. It’s all documented in the previous post so you can use that to get to this stage.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_2ec9382c7123ddfc.png)

2.  We need an application configured in Azure Active Directory just as per my previous post. In this post, I’ve created a new application I’ve called <font face="Courier New"><font style="font-size: 10pt" size="2">sso.lewisroberts.com</font></font>. There’s no special configuration required for the application.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_ea03a6772a53a933.png)

# Import federation data from Azure application to SimpleSAMLphp

1.  Open the Windows Azure Management portal and navigate to your application. Click **View Endpoints** in the grey banner at the bottom.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_fa96c9f678cdd14c.png)

2.  In the **App Endpoints** window. Copy the URL for the **Federation Metadata Document**.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_de84545dbb5234a0.png)

3.  Using your favourite browser, navigate to the location and save the metadata document. How you do this doesn’t really matter, as long as it’s just the XML you save.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_fa6c9253e99f2bd6.png)

4.  Open the <font face="Courier New"><font style="font-size: 10pt" size="2">federationmetadata.xml</font></font> file in a text editor, select the entire contents (Ctrl+A) and then copy it to the clipboard.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_48b1a6b055690be9.png)

5.  Open a browser and navigate to <font face="Courier New"><font style="font-size: 10pt" size="2">https://sso.lewisroberts.com/simplesaml</font></font>_(Actually, you’ll obviously navigate to your own PHP application’s website, not mine_._)_ Once there, click the **Federation** tab.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_d0272e256ebbf6dd.png)

6.  On the **Federation** tab, look for **Tools** and then click **XML to simpleSAMLphp metadata converter**.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_714122b136f6ed85.png)

7.  Paste the entire <font face="Courier New"><font style="font-size: 10pt" size="2">federationmetadata.xml</font></font> file’s contents in to the field and click the **Parse** button.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_bcd944b85469b967.png)

8.  The page should return almost immediately with some information similar to the following under the Converted metadata section. Copy the contents of the **saml20-idp-remote** field to your clipboard, or a file, it’s your choice.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_8ee2fef516c83c65.png)

9.  Navigate to your SimpleSAMLphp installation folder and find the <font face="Courier New"><font style="font-size: 10pt" size="2">metadata</font></font> folder.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_7b4ebeb3791e9c31.png)

10.  Now open the <font face="Courier New"><font style="font-size: 10pt" size="2">saml20-idp-remote.php</font></font> file.  
    _Did you notice? The converted metadata returned from SimpleSAMLphp had the field set to saml20-idp-remote – the same name as the file we’re editing._  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_257bca8b6855a500.png)

11.  Now copy the converted metadata contents in to the file. I’ve highlighted where this was pasted in to my own version of the file. Do note however that obviously the converted metadata extends beyond the bottom of the visible screen I show here. It should be a simple matter of pasting in the converted metadata. Save the file.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_5fa2df932bd1db71.png)

# Configure SimpleSAMLphp as a service provider

1.  Navigate to your SimpleSAMLphp installation folder and open the <font face="Courier New"><font style="font-size: 10pt" size="2">config</font></font> folder.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_77d8ddc14fc33d42.png)

2.  Open <font face="Courier New"><font style="font-size: 10pt" size="2">authsources.php</font></font> in your favourite text editor.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_342275eab60a61d9.png)

3.  There are a number of authentication sources preconfigured (but commented out) however the one we’re interested in (or rather, its general format) is <font face="Courier New"><font style="font-size: 10pt" size="2">default-sp</font></font>. I’ve shown this (actually, the interesting bits) in its default state, below.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_4bf3deabaa316e6e.png)

4.  In order to achieve compatibility with Azure AD, we need to make some small changes to default-sp. We _could_ just create another authsource called something else but it’s easier to show what it looks like initially and then edited if we change default-sp. The next few steps will show where we make edits.

5.  Firstly, change the <font face="Courier New"><font style="font-size: 10pt" size="2">entityID</font></font> value to reflect the name or URL of your Azure application.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_c9807be520d63cf4.png)

6.  Next, enter the <font face="Courier New"><font style="font-size: 10pt" size="2">idp</font></font> value. Where did I get this from? The very first line of the converted metadata actually gives you the IdP (Identity Provider) – in this case, Azure AD.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_e6ec21375e049871.png)

7.  <font face="Courier New"><font style="font-size: 10pt" size="2">discoURL</font></font> stays as null.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_29fba6ed476a169d.png)

8.  Next we must add some additional information that is required to communicate with Azure AD. Underneath discoURL, add the following two lines.

<div id="crayon-5f9b6b2f0d3a1465768195" dir="ltr">

<font style="font-size: 9pt" size="2">PHP</font>

<font style="font-size: 9pt" size="2">'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', 'simplesaml.nameidattribute' => 'eduPersonTargetedID',</font>

<dl>

<dd>

<table cellspacing="2" cellpadding="2">

<tbody>

<tr>

<td style="border: none; padding: 0cm">

<font style="font-size: 9pt" size="2">1</font>

<font style="font-size: 9pt" size="2">2</font>

</td>

<td style="border: none; padding: 0cm">

<div id="crayon-5f9b6b2f0d3a1465768195-1" dir="ltr">

'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',

</div>

<div id="crayon-5f9b6b2f0d3a1465768195-2" dir="ltr">

'simplesaml.nameidattribute' => 'eduPersonTargetedID',

</div>

</td>

</tr>

</tbody>

</table>

</dd>

</dl>

</div>

![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_3ac0656fd59443fa.png)

2.  We’re complete editing <font face="Courier New"><font style="font-size: 10pt" size="2">authsources.php</font></font> so save and close the file.

# Testing authentication

Now that configuration of SimpleSAMLphp is complete, we can use SimpleSAMLphp to test authentication works as expected, without actually writing any code but we’ll get to that in a second.

1.  Navigate to <font face="Courier New"><font style="font-size: 10pt" size="2">https://sso.lewisroberts.com/simplesaml</font></font> (remember, your own app, not mine, this is an example.) and then click the **Authentication** tab.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_f59c405fedf73d44.png)

2.  Once there, click **Test configured authentication sources**  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_4534164b7c38c60d.png)

3.  We should see only two options<font face="Courier New"><font style="font-size: 10pt" size="2">, admin</font></font> and <font face="Courier New"><font style="font-size: 10pt" size="2">default-sp</font></font>. These were the only two authentication sources defined in <font face="Courier New"><font style="font-size: 10pt" size="2">authsources.php</font></font>. Click **default-sp**.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_11041f933f74499f.png)

4.  You will likely receive an error that looks as follows. This means that the **Reply URL** sent by SimpleSAMLphp to Azure AD as part of the authentication attempt isn’t one that is accepted by the application. So it’s not very happy. To fix this, we need to quickly visit the Azure Management portal and add this **Reply URL** to our application.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_6f7db804cde7734c.png)

5.  First, copy the URL from the error. In this case, the URL is: <font face="Courier New"><font style="font-size: 10pt" size="2">https://sso.lewisroberts.com/simplesaml/module.php/saml/sp/metadata.php/default-sp  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_d2eccaa06c787161.png)</font> </font>

6.  In the Azure Management portal, find the application, scroll to **Single Sign-On** and add it to the list of **Reply URLs**. Save the configuration change but leave the management portal open in case you must make any more edits.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_acd4033a43ca7a47.png)

7.  Close the other browser showing the error, open another and repeat steps 1 to 3.  
    After clicking on **default-sp** now that we have added the **Reply URL** in to the Windows Azure portal, we should be shown the **Sign in** page.  
    _Notice the URL we’re sent to. This is the actually the_ _**SAML-P Sign On Endpoint**_ _for the Azure application._  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_6cc6dada0eb3540c.png)

8.  Log in with a user account that’s in your Azure Active Directory.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_de91827c6dd84fd.png)

9.  We should now be able to sign in without error and get redirected back to SimpleSAMLphp and shown a list of the claims that were sent along with the authentication.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_97381aa04f6183fb.png)

10.  To test logging out, click **Logout**.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_33ea71832ef47d66.png)

# Custom PHP application code

So, all this configuration was just to get us to the point where we can create our own application code that allows us to authenticate with Azure AD. The reality is that our PHP “application” can be a single page.

## index.php
Generally, the application will require an index.php file – the code for which is below. I’ll give a very brief breakdown of the first few lines, the rest is obvious.
```php
<?php
require_once (dirname(__FILE__) . '/../simplesamlphp/lib/_autoload.php');
$as = new SimpleSAML_Auth_Simple('default-sp');
$as->requireAuth();

$attributes = $as->getAttributes();

?>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Index Page</title>
</head>
<body>
    <h2>Index Page</h2>
    <h3>Welcome <strong>Authenticated User</strong>!</h3>
    <h4>Claim list:</h4>
<?php
echo '<pre>';
print_r($attributes);
echo '</pre>';

// Get a logout URL
$url = $as->getLogoutURL();
echo '<a href="' . htmlspecialchars($url) . '">Logout</a>';

?>
</body>
</html>
```


This file will require authentication so, on line 2, it calls SimpleSAMLphp’s autoloader from the main installation of SimpleSAMLphp.

On line 3, we create a new object from the SimpleSAML_Auth_Simple class but notice here we specify the authsource <font face="Courier New"><font style="font-size: 10pt" size="2">default-sp</font></font> – that’s correct, we’re associating this application with the <font face="Courier New"><font style="font-size: 10pt" size="2">default-sp</font></font> auth source we created.

On line 4, we use the object and tell it we require authentication. If the user is authenticated, the script will proceed to the next line, if not however, they will begin the authentication process and be redirected to Azure AD to sign in. Once signed in, they will be redirected back to this page.

On line 6, we pull the attributes from the SAML token and store them in the $attributes array. These are then used later (line 21) to show the user their claims.

On line 25 we get a logout URL from the <font face="Courier New"><font style="font-size: 10pt" size="2">$as</font></font> object and send that back to the interface so the user can click a link to log out.

1.  The user navigates to the web application. Given they’re not logged in, they’re automatically redirected to the Azure AD sign in page.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_dec2608edd73bf73.png)

2.  The user lands at the Azure AD sign in page.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_50ae7bc4871617aa.png)

3.  The user logs in with a valid Azure AD account.  
    _Notice as well that the page also says_ _<font face="Courier New"><font style="font-size: 10pt" size="2">sso.lewisroberts.com</font></font>_ _– a bit of free branding._  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_8d239220edda0706.png)

4.  After successfully authenticating, the user is redirected back to the site where they can see their claims and a logout link.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_da7360d37776a6ea.png)

5.  When clicking the **Logout** link, the user is logged out of their account.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_94ef2c7a676780d4.png)

# A little something extra?

One thing I’ve wondered while doing all this was whether we could get additional claims through rather than just those few that are shown in the screenshots. Something like groups would be great. As it turns out, that feature was introduced at the back end of 2014. I’ll run through it very quickly in the context of our application but for more details (and how to handle users who might be members of more than 150 groups (in SAML)) you really should [visit the blog of Dushyant Gill](http://www.dushyantgill.com/blog/2014/12/10/authorization-cloud-applications-using-ad-groups/).

1.  In the Windows Azure management portal, navigate to your application and click **Manage Manifest** then **Download Manifest**.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_e68bdd707b6f9230.png)

2.  Download the manifest file and save it to disk. Leave the portal open, you’ll need it shortly.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_4abeaf105fb46806.png)

3.  Open the file in any decent text editor. I’ve chosen to do it in Visual Studio code. Locate the <font face="Courier New"><font style="font-size: 10pt" size="2">groupMembershipClaims</font></font> value.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_531db411762659d4.png)

4.  Change this to one of <font face="Courier New"><font style="font-size: 10pt" size="2">SecurityGroup</font></font> or <font face="Courier New"><font style="font-size: 10pt" size="2">All</font></font>.

    *   <font face="Courier New"><font style="font-size: 10pt" size="2">SecurityGroup</font></font> – The <font face="Courier New"><font style="font-size: 10pt" size="2">groups</font></font> claim will contain the identifiers of all security groups that the user is a member of.

    *   <font face="Courier New"><font style="font-size: 10pt" size="2">All</font></font> – The <font face="Courier New"><font style="font-size: 10pt" size="2">groups</font></font> claim will contain the identifiers of all security groups and distribution lists that the user is a member of.

5.  I’ve chosen to just enable <font face="Courier New"><font style="font-size: 10pt" size="2">SecurityGroup</font></font> option in the screenshot below. Save the file.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_8387e801d583df2.png)

6.  Back on the portal site, **Manage Manifest** and then click **Upload Manifest**.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_be9cfe1d2f1232ae.png)

7.  Browse for the saved file and then click the tick icon to upload it.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_21be36e8b30e9e8.png)

8.  **Dushyant’s post goes on to mention that you should grant additional permissions in the application. This is only really required** **_if_** **you are going to be dealing with “overage” scenarios which means users who are members of more than 150 groups, since these can’t be included in the SAML token. Read [his blog post for more info](http://www.dushyantgill.com/blog/2014/12/10/authorization-cloud-applications-using-ad-groups/). For our demo app purposes, our user is a member of only one group.**

9.  So, I’ve created a group in my Azure AD and added the user to it. Note the **Object ID**, this is the value that will be shown in the claim.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_56a106814b1e0105.png)  
    Members  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_ff4a1a630e232295.png)

10.  Now if we re-try our authentication (and without making any code changes to our <font face="Courier New"><font style="font-size: 10pt" size="2">index.php</font></font> file) we see that the <font face="Courier New"><font style="font-size: 10pt" size="2">groups</font></font> claim is carried through in to the application. Of course this means you can use it for security trimming etc. within your custom app.  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_fce8d54ca6e2ec46.png)  
    _**Note**__: I noticed that there was another group id in the claim – I’m assuming this is related to this user’s status as a Global Administrator since if I authenticate as a user who is purely a member of the LocalAzureAD group, the only groups claim attribute is the Object ID of the LocalAzureAD group._  
    ![](Single_Sign_on_to_Azure_AD_using%20SimpleSAMLphp_html_ba038090900fb500.png)

So, another not insignificant post ends and hopefully you’ve learned a little something along the way. Seeing that it’s possible to pull group claims through in to the application opens a lot of possibilities for developers of bespoke PHP applications and I’m sure it’ll be very handy to know in the future.

I think I’ve got one more post in me about SimpleSAMLphp and that is probably going to be integrating SimpleSAMLphp with ADFS 2012R2\. That post will hopefully be shorter since we’ll be repeating a lot of the activities we’ve done above. For example, instead of importing the federation metadata from our Azure Application, we’ll import from the ADFS server and set that up in SimpleSAMLphp. We’ll configure our PHP “application” as a Relying Party Trust and get all the necessary information automatically from simpleSAMLphp and finally configure the ADFS server as the IdP for the application.