SimpleSAMLphp

A PHP library for SSO, Single Sign On


Introduction

SimpleSAMLphp is a tool for enabling single sign on, which is where you use one website to authenticate (login) users for multiple other websites. You can find more information here: https://simplesamlphp.org. Hopefully, this tutorial will give you a good start before you dive into their documentation, which can be confusing and intimidating for newbies.

Terminology

Here are some abbreviations I'll use and what they mean:

(SSO) Single Sign On the simple concept of having one website handle user log ins for multiple websites.
(IDP) Identity Provider the one website that stores user names and passwords to handle log ins.
(SP) Service Provider any of the other websites that use the IDP for authentication.
(SAML) Security Assertion Markup Language a protocol used to implement SSO.
(Shib) Shibboleth an extension of the SAML protocol. Usually compatible with SAML.

SimpleSAMLphp supports SAML 2.0 and Shib 1.3

What This Tutorial Covers

What This Tutorial Covers
  1. Installation
  2. Configure An IDP With Shibboleth 1.3
  3. Configure An SP With SAML 2.0

What You Need For This Tutorial

What You Need For This Tutorial

If you're just trying to set up an SP that will integrate with someone else's IDP, all you need will be the following information:

  1. The IDP's Entity ID
  2. The url where the IDP's metadata can be downloaded

Otherwise, if you plan on setting up both an IDP and SP, you will need:

You need 2 domain names. The IDP & SP need to store separate browser cookies. Being on the same domain causes their cookies to conflict and it won't work. You can use different subdomains though. For example, you can run your IDP on federation.example.com & your SP on example.com

You need 2 servers. IDPs & SPs can be on the same server, but to simplify things, we'll be installing them on separate servers. I usually use the cheapest servers on Digitial Ocean for testing this kind of stuff.

Ubuntu, Apache, Apache-PHP module. While you can try following along with different tools, I'll be doing everything on Ubuntu with Apache and the necessary Apache modules to run PHP scripts installed. This tutorial does not go over installing Apache & it assumes you're fairly familiar with Apache & PHP. We will go over configuring Apache to work with SimpleSAMLphp though.


Important! Do everything in this tutorial on both your SP & IDP.


Choose Your Entity IDs

You need an SP entity ID and an IDP entity ID. These can be any arbitrary string and they're used to identify an SP or IDP. Most people use the URL where their SP or IDP is located.


Installation

Installing SimpleSAMLphp requires Composer, a php package manager. So we need to download SimpleSAMLphp & Composer. You might need to check if a newer version is available at their websites: simplesamlphp.org & getcomposer.org. You can install SimpleSAMLphp anywhere, but I'm going to install it in the /var directory


# install composer and move it directory in $PATH so it can be called from anywhere    
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

# download simplesamlphp, untar it, move it to directory, remove tar, install it with composer
wget https://github.com/simplesamlphp/simplesamlphp/releases/download/v1.14.11/simplesamlphp-1.14.11.tar.gz -P /var
tar -xvzf /var/simplesamlphp-1.14.11.tar.gz -C /var
mv /var/simplesamlphp-1.14.11 /var/simplesamlphp
rm /var/simplesamlphp-1.14.11.tar.gz
composer install -d /var/simplesamlphp
      

Depending on your exact set up of Ubuntu, you may need some extra packages for composer install to work. You should try to figure out which ones based on the error report composer install prints out, but listed below are some packages I had to install for Ubuntu 16.04


apt-get install -y php-xml php-sqlite3 php-curl php-gmp php-zip
apt-get install -y git
      

Configure Apache

We need to configure Apache to route requests to simplesamlphp.

Open your site's configuration file in /etc/apache2/sites-available/.

Add the code below to the file. On your IDP replace sp with idp.


SetEnv SIMPLESAMLPHP_CONFIG_DIR /var/simplesamlphp/config
Alias /sp/simplesaml /var/simplesamlphp/www
<Directory /var/simplesamlphp/www>
<IfModule !mod_authz_core.c>
        # For Apache 2.2:
        Order allow,deny
        Allow from all
</IfModule>
<IfModule mod_authz_core.c>
        # For Apache 2.4:
        Require all granted
</IfModule>
</Directory>
      

Configure SimpleSAMLphp

Now we need to configure simplesamlphp.

First, we need to generate an encrypted administrator password and a secret salt. Save the outputs of the following commands:


# generate encrypted administrator password
/var/simplesamlphp/bin/pwgen.php

# genereate random string of characters to use as secrent salt
tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo
      

Open /var/simplesamlphp/config/config.php.

Make the following edits. On your IDP replace sp with idp.


'baseurlpath' => 'sp/simplesaml/'
'auth.adminpassword' => 'Enter your encrypted adminstrator password here, what you generated before'
'admin.protectindexpage' => true
'secretsalt' => 'Enter your random secret salt, which you generated before'
'technicalcontact_name' => 'Enter any name you want'
'technicalcontact_email' => 'Enter any email address you want'
'timezone' => 'Enter your timezone here (http://php.net/manual/en/timezones.php)'
'metadata.sources' => array(
    array('type' => 'flatfile'),
    array('type' => 'flatfile', 'directory' => 'metadata/remote'),
)
      

In the same file, but only for your IDP, change the following:


'enable.shib13-idp' => true
      

You need an SSL certificate for SSO. Run the following command to generate one.


openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out /var/simplesamlphp/cert/saml.crt -keyout /var/simplesamlphp/cert/saml.pem
      

Enable The Cron & Metarefresh Modules.

These are for running cron jobs on simplesamlphp and fetching IDP and SP metadata remotely, so you don't have to store metadata locally. Run the following commands:


touch /var/simplesamlphp/modules/cron/enable
cp /var/simplesamlphp/modules/cron/config-templates/*.php /var/simplesamlphp/config/
touch /var/simplesamlphp/modules/metarefresh/enable
cp /var/simplesamlphp/modules/metarefresh/config-templates/*.php /var/simplesamlphp/config/
      

Configure the metarefresh module.

Open /var/simplesamlphp/config/config-metarefresh.php.

Delete everything inside the file and enter the code below.

Replace SOURCE with the URL where you can fetch metadata. In this case, use the following URLs (replace DOMAIN with your domain name & replace SP-ID with your SP entity ID).

If on your SP, use: https://DOMAIN/idp/simplesaml/shib13/idp/metadata.php.

If on your IDP, use: https://DOMAIN/sp/simplesaml/module.php/saml/sp/metadata.php/SP-ID


$config = array(
  'sets' => array(
    'refresh' => array(
      'cron' => array('hourly'),
      'sources' => array(
        array(
          'src' => 'SOURCE'
        ),
      ),
      'expireAfter' => 60*60*24*4, // Maximum 4 days cache time
      'outputDir' => 'metadata/remote/',
            'outputFormat' => 'flatfile',
        ),
  ),
);
      

Create the directories to store the remotely fetched metadata. By the way, SAML metadata is an XML file that contains a bunch of data about an IDP or SP that's needed for the connection. Run the following commands:


mkdir /var/simplesamlphp/metadata/remote
chown www-data /var/simplesamlphp/metadata/*
      

Configure the cron module.

Open /var/simplesamlphp/config/module_cron.php.

Simply add the secret salt you generated earlier to this file.


'key' => 'Your secret salt'
      

Set up a cron job to periodically fetch remote metadata.

First, go to (replace DOMAIN your domain name): https://DOMAIN/sp/simplesaml/module.php/cron/croninfo.php.

Run the following command to open up your cron job file with an editor:


crontab -e
      

Paste what you copied from the URL into the file that opened up and save it.

Repeat what you just did, but this time copy the contents from this URL: https://DOMAIN/idp/simplesaml/module.php/cron/croninfo.php.


Enable Auth Module

This is the only step that's significantly different between the IDP & SP

Open /var/simplesamlphp/config/authsources.php.

Delete everything in the file and paste in the following if on your IDP (you might want to keep a copy of what your deleting as it has examples of other types of configurations):


<?php

$config = array(
    'admin' => array(
        'core:AdminPassword',
    ),

    'example-userpass' => array(
        'remember.username.enabled' => TRUE,
        'remember.username.checked' => TRUE,
        'exampleauth:UserPass',
        
        'firstUser:firstPassword' => array(
            'firstKey' => array('any value you want'),
            'secondKey' => array('you can store', 'several values per key'),
        ),
        'secondUser:secondPassword' => array(
            'firstKey' => array('any value you want'),
            'secondKey' => array('you can store', 'several values per key'),
        )
    )
);
      

Do the same thing for your SP, but paste in the following:


<?php

$config = array(
    'admin' => array(
        'core:AdminPassword',
    ),

    'Your SP entity ID' => array(
        'saml:SP',
        'privatekey' => 'saml.pem',
        'certificate' => 'saml.crt',
        'entityID' => 'Your SP entity ID',
        'idp' => 'Your IDP entity ID',
        'discoURL' => null,
     ),
);
      

In the code above, we're storing user data directly in the file. You can add whatever you want for users. The syntax is 'username:password' => array('key'=>array('values')). This is obviously very insecure and you should choose a different method for storing user data if you're trying to set up a legit IDP. If you're interested in doing that, the comments in authsources.php show you a lot of possible options. You can find out a little more here: https://simplesamlphp.org/modules. Anyways, we're only setting up the IDP for testing, so we're doing the easy version.

Enable the ExampleAuth module for the IDP

You only need to do this on the IDP. It is the module for authenticating.

Run the following command:


touch /var/simplesamlphp/modules/exampleauth/enable
      

Configure metadata for IDP.

IDP and SP metadata is stored in /var/simplesamlphp/metadata. In this case, we only need to explicitly set up metadata for the IDP. Again, you only need to do this on the IDP.

Open /var/simplesamlphp/metadata/shib13-idp-hosted.php.

Make the following edits to the file:


$metadata['Your IDP entity ID'] = array(
  'host' => '__DEFAULT__',
  'privatekey' => 'saml.pem',
  'certificate' => 'saml.crt',
  'auth' => 'example-userpass',
);
      

Testing SimpleSAMLphp Set Up

To test your configuration, you can go to https://DOMAIN/sp/simplesaml. Replace sp with idp to go to your IDP configuration page.

You'll have to log in using the admin password you created earlier. This has four tabs has some useful tools.

Welcome Not much here. Just links to documentation.
Configuration General information about what features and modules you have enabled.
Authentication This is where you go to test if your set up is working.

Click on the link 'Test configured authentication sources'.

If you're testing just the IDP, click the link 'example-userpass'. If you're testing the SP, click the link with your SP entity ID.

This should take you to a place where you can log in using one of the users you created. If you didn't change the code I provided, you can use firstUser and firstPassword. After logging in, you should see their associated data.
Federation This shows what IDPs & SPs you have configured and are accepting connections from.

It also has metadata tools, like the ability to manually refresh an IDP or SP's metadata.

Integrating SimpleSAMLphp Into A Website

On the SP, place the following code in any php file where you want to require authorization from the IDP.


require_once('/var/simplesamlphp/lib/_autoload.php');
$auth = new SimpleSAML_Auth_Simple('Your SP entity ID');
$auth->requireAuth();
      

When a user goes to your page, they'll be redirected to the IDP for login. If successful, they'll return to your file, and anything past $auth->requireAuth(); will load.

You can view what methods the SimpleSAML_Auth_Simple object has here: https://simplesamlphp.org/docs/1.5/simplesamlphp-sp-api

Most people will just need the following method to get the user attributes:


$auth->getAttributes();
      

Done!

That was pretty long. I hope you made it!