SimpleSAMLphp

A php library that gets your website on SSO, Single Sign On

Reminder, try sudo if something fails, variables are marked as @@VARIABLE@@, and content is color coded based on whether they're shell commands or file content.


Introduction

SimpleSAMLphp is a tool used 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.

(SSO) Single Sign On: the simple concept of having one website handle user log ins for multiple websites.

(IDP) Identity Service 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

1. We'll cover installing SimpleSAMLphp on your servers.

2. We'll configure an IDP using Shibboleth 1.3. While most people only need to configure an SP, the IDP will be used to test that the SP works correctly.

3. We'll configure an SP using SAML 2.0.

What You Need For Just The Tutorial

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.

What You Need To Integrate With An IDP

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

1. The IDP's Entity ID

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


Do Everything On Both Servers

Complete these instructions on both the IDP server & the SP server.

@@IDPSP@@

"idp" or "sp" depending on which server you are on.

@@DOMAIN@@

The domain name of the IDP or SP. For example, IDP can use federation.example.com and SP can use example.com

@@SP-ID@@

The entity ID of the SP. This can be anything really. Most people choose their url.

@@IDP-ID@@

The entity ID of the IDP. This can be also be anything.


Install SimpleSAMLphp

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

copy
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/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

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

Configure Apache

Unless you changed the location of your SimpleSAMLphp installation, you can just add this to your Apache website configuration file exactly how it is.

If you changed the location of your SimpleSAMLphp installation, change /var/simplesamlphp/config and /var/simplesamlphp/www in 3 places.

On Ubuntu, open and add to your website configuration file in /etc/apache2/sites-available/

copy
SetEnv SIMPLESAMLPHP_CONFIG_DIR /var/simplesamlphp/config
Alias /@@IDPSP@@/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>

Generate Admin Password & Salt

@@ADMINPASS@@

The output of the first command below.

@@SECRETSALT@@

The output of second command below.

Save the output of these two commands. It will be the hash for your admin password & the salt that SimpleSAMLphp uses for creating secure hashes.

copy
/var/simplesamlphp/bin/pwgen.php
									
tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo

Configure config.php

@@CONTACTNAME@@

A name people will see in case of errors.

@@CONTACTEMAIL@@

An email people will see in case of errors.

@@TIMEZONE@@

The timezone of your server. Valid timezones can be found here: http://php.net/manual/en/timezones.php


copy
vim /var/simplesamlphp/config/config.php
copy
'baseurlpath' => '@@IDPSP@@/simplesaml/'
'auth.adminpassword' => '@@ADMINPASS@@'
'admin.protectindexpage' => true
'secretsalt' => '@@SECRETSALT@@'
'technicalcontact_name' => '@@CONTACTNAME@@'
'technicalcontact_email' => '@@CONTACTEMAIL@@'
'timezone' => '@@TIMEZONE@@'
'metadata.sources' => array(array('type' => 'flatfile'),array('type' => 'flatfile', 'directory' => 'metadata/remote'),)

Also change the following for just the IDP

copy
'enable.shib13-idp' => true

Generate SSL Certificate

Using SAML requires the use of SSL certificates (which makes your site https: and not http:)

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

Enable Cron & Metarefresh Modules

The cron module enables the ability to run regular commands (it uses cron jobs) and the metarefresh module enables the ability to fetch IDP and SP metadata remotely.

copy
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 config-metarefresh.php

@@SOURCE@@

The url of the location of either the IDP or SP metadata to retrieve (in other words, if on the IDP, put the SP metadata url, and vice versa).
In this case, the IDP source will be: https://@@DOMAIN@@/idp/simplesaml/shib13/idp/metadata.php
The SP source will be: https://@@DOMAIN@@/sp/simplesaml/module.php/saml/sp/metadata.php/@@SP-ID@@

You can delete everything inside the next file, and paste in the provided code.

copy
vim /var/simplesamlphp/config/config-metarefresh.php
copy
$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 Directory For Remote Metadata

SAML metadata is an xml file that contains a bunch of data about the IDP or SP you're connecting to. They're required when creating a connection. This directory will store new metadata as it's retrieved.

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

Configure module_cron.php

The Cron module requires a randomized string to work. You can reuse the salt you generated earlier.

copy
vim /var/simplesamlphp/config/module_cron.php
copy
'key' => '@@SECRETSALT@@'

Set Up Cron Job

@@CRONINFO@@

The contents of the croninfo.php url below.

Go to and copy the contents in https://@@DOMAIN@@/@@IDPSP@@/simplesaml/module.php/cron/croninfo.php

Running the following command will open up a file in an editor. Paste in the contents from the previous url.

copy
crontab -e
copy
@@CRONINFO@@

Configure authsources.php

This is the only step that's significantly different between the IDP & SP. You can delete everything in the following file and paste in the code. It might be useful to store a copy of it though.

copy
vim /var/simplesamlphp/config/authsources.php

Paste in the following for the SP

copy
<?php

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

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

Paste in the following for the IDP

copy
<?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'),
        )
    )
);

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 ExampleAuth Module For IDP

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

copy
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.

copy
vim /var/simplesamlphp/metadata/shib13-idp-hosted.php
copy
$metadata['@@IDP-ID@@'] = array(
        'host' => '__DEFAULT__',
        'privatekey' => 'saml.pem',
        'certificate' => 'saml.crt',
		'auth' => 'example-userpass',
);

Testing SimpleSAMLphp

To test your configuration, you can go to https://@@DOMAIN@@/@@IDPSP@@/simplesaml

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 '@@SP-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 Your Website

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

copy
require_once('/var/simplesamlphp/lib/_autoload.php');
$auth = new SimpleSAML_Auth_Simple('@@SP-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.

copy
$auth->getAttributes();

Done!

That was pretty long. I hope you made it!