SAML 2.0 with simplesaml setting up a service provider and an identity provider.
What are SAML, SSO and SimpleSAMLphp?
Single Sign On is authentication in one point for N providers. A user will log into a SAML2.0 Identity Provider. In our case the IdP is a SAML module, but it can be a LDAP, RADIUS, Facebook, or Twitter entity. Once the user is authenticated in the IdP, the credentials/session will be valid for any Service Provider (basically any website) that has a valid conection with the IdP. The entire authentication process is done via the exchanging of XML metadata between an IdP and an SP. Also, the IdP and SP exchange cerficates will sign SAML tokens. In this way, the SSO process is supposed to be secure and reliable. As a quick note, the SAML tokens can be encrypted as well. However, we won't cover that in this article.
SAML (Security Assertion Markup Language): SSO protocol that supports XML to exchange data between SPs and IdPs.
Simplesamlphp: The UNINETT and many contributers have implemented the SAML protocol in PHP. Thanks to them, using this library makes implementing SAML/SSO just a mere setup of 'configurations'. I'll refer to this library as 'SAML' in this article.
Benefits
- Users only have to remember one username and password instead of N credentials for N websites.
- Users don't have to relogin everytime they are trying to visit a website (a SP).
- Users' data is stored only in a unique database (this depends on the implementation).
Installation:
The SAML installation tends to be tedius if you lack knowledge of Apache, Nginx, Linux, etc. This article is only about the configuration of an SP and an IdP, although you can use this release of a Vagrant machine configuration which provides a Drupal 7 and SAML installation. Download it and run it to start following this article right away. This is the article with the steps to create the Vagrant Machine and here's the github.
Here are some basic steps to install SAML (jump to the next section if you have already installed it).
Based on SAML's website, these are the minimum requirements:
- PHP >= 5.3
- Memcache to store sessions. You could use sqli, or phpsessions. However, we will use a memcache.
- A PHP library to connect to Memcache. Although you really only need memcache, I recommend that you install both PHP libraries, memcache and memcached, to avoid confusion. Normally you install these libraries with pecl /usr/local/bin/pecl install memcache which generates a .so bin that has to be loaded with the php.ini.
- PHP extensions: date, dom, hash, libxml, openssl, pcre, SPL, zlib, mcrypt
Download the library SAML: https://simplesamlphp.org/download. This article assumes you are using the version 1.13.
Once downloaded, place it into /var/simplesaml
. Point the URL http://localhost/simplesaml
to /var/simplesaml/www
.
You can do this with Apache using the following:
<virtualhost> ServerName service.example.com DocumentRoot /var/www/service.example.com SetEnv SIMPLESAMLPHP_CONFIG_DIR /var/simplesamlphp/config Alias /simplesaml /var/simplesamlphp/www </virtualhost>
Or using Nginx:
location /simplesaml { alias /var/simplesaml/www; try_files $uri $uri/ /index.php?$query_string; location ~ \.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.+)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; } }
Service Provider:
As of 2015, the IdP Feide OpenIdP no longer lets users test SAML's Service Providers against it. We will create a local SP and IdP to overcome this.
Configuring a SP in config/authsources.php
<!--?php // This is a authentication source which handles admin authentication. // SAML will use this authentication source to do its own authentication. // The module used for this is core:AdminPassword, but it can be replaced with // any authentication source. 'core:AdminPassword', ), 'saml:SP', //we want to use SAML for this SP 'entityID' => 'http://192.168.33.99/simplesaml/idp', //this is the ID for this SP, later on it will be used in the IdP 'privatekey' => 'saml.pem', //stored in simplesaml/cert 'certificate' => 'saml.crt', //stored in simplesaml/cert ), );
Generating a certificate:
We need a certificate to sign assertions (on SLI and SLO).
In your SAML installation create a folder.
And create a certificate.
openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out saml.crt -keyout saml.pem -subj "/C=US/ST=Denial/L=Oakland/O=Dis/CN=192.168.33.99" //using -subj to automatizate this process later on
Telling our SP about the IdP
Add the IdP's metadata into the file metadata/saml20-idp-remote.php. If you are using the Vagrant box simplesamlphp, it can be found in
http://192.168.33.99/simplesaml/saml2/idp/metadata.php.
This part is a little tricky because you have to first configure the IdP and get its metadata. The instructions to configure a local IdP are below.
Note: If you are setting up an external IdP and have the XML data, then convert it into an array using the SAML's converter in
http://192.168.33.99/simplesaml/admin/metadata-converter.php
Add the array to metadata/saml20-idp-remote.php
'metadata-set' => 'saml20-idp-remote', 'entityid' => 'http://192.168.33.99/simplesaml/saml2/idp/metadata.php', 'SingleSignOnService' => array ( 0 => array ( 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'Location' => 'http://192.168.33.99/simplesaml/saml2/idp/SSOService.php', ), ), 'SingleLogoutService' => array ( 0 => array ( 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'Location' => 'http://192.168.33.99/simplesaml/saml2/idp/SingleLogoutService.php', ), ), 'certData' => 'MIIDhTCCAm2gAwIBAgIJAJWSkrMdkaKeMA0GCSqGSIb3DQEBC...', 'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', );
Identity Provider:
Enabling SAML as IdP
SAML2.0 has to be enabled in config/config.php
'enable.saml20-idp' => true,
Enabling and configuring an authentication source
You will retrieve 'identities' from the IdP - therefore the IdP has to request users's data (i.e. username, password, firstname, lastname) from somewhere. Here's where LDAP, RADIUS, a SQL database, Facebook, Twitter etc. comes into play to provide these entities/identities. In our case, we will use a built-in authentication method that the library provides. As a quick note: users' data in SAML are called attributes and claims in Windows Server.
Enabling example UserPass module
Configuring authentication source
This has to be configured in config/authsources.php
<!--? php 'exampleauth:UserPass', ), ), ), );
At this point the file config/authsources.php should look like this:
// SAML will use this authentication source to do its own authentication. // The module used for this is core:AdminPassword, but it can be replaced with // any authentication source. 'core:AdminPassword', ), 'saml:SP', //we want to use SAML for this SP 'entityID' => 'http://192.168.33.99/simplesaml/idp', //this is the ID for this SP, later on it will be used in the IdP 'privatekey' => 'saml.pem', //stored in simplesaml/cert 'certificate' => 'saml.crt', //stored in simplesaml/cert ), 'exampleauth:UserPass', ), ), ), );
Creating a certificate for the IdP
$ cd simplesamlphp & cd cert $ openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out idp.crt -keyout idp.pem -subj "/C=US/ST=Denial/L=OaklandIdP/O=Dis/CN=192.168.33.99"
Configuring the local IdP
The IdP is configured in metadata/saml20-idp-hosted.php
/* * '__DEFAULT__' to use the IP (192.168.33.99) of the host by default */ 'host' => '__DEFAULT__', /* Stored into the folder cer */ 'privatekey' => 'idp.pem', 'certificate' => 'idp.crt', /* * In authsources.php we created this authenticated source */ 'auth' => 'molanco-authentication', );
Adding the SP to our local IdP
You have to tell the IdP what SPs will be comunicating with it. Again, this step is a little bit tricky because in order to get the SP's metadata, first you need to tell the SP about our IdP (adding the IdP's metadata to the SP). At this point you can get the IdP's metadata from simplesaml/module.php/core/frontpage_federation.php. If you haven't done so already, go back to "Telling our IdP about the SP". If you have the SP's metadata then add it to metadata/saml20-sp-remote.php.
'SingleLogoutService' => array ( 0 => array ( 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'Location' => 'http://192.168.33.99/simplesaml/module.php/saml/sp/saml2-logout.php/openidp', ), ), 'AssertionConsumerService' => array ( 0 => array ( 'index' => 0, 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'Location' => 'http://192.168.33.99/simplesaml/module.php/saml/sp/saml2-acs.php/openidp', ), 1 => array ( 'index' => 1, 'Binding' => 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post', 'Location' => 'http://192.168.33.99/simplesaml/module.php/saml/sp/saml1-acs.php/openidp', ), 2 => array ( 'index' => 2, 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact', 'Location' => 'http://192.168.33.99/simplesaml/module.php/saml/sp/saml2-acs.php/openidp', ), 3 => array ( 'index' => 3, 'Binding' => 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01', 'Location' => 'http://192.168.33.99/simplesaml/module.php/saml/sp/saml1-acs.php/openidp/artifact', ), ), 'certData' => 'MIIDfzCCAmegAwIBAgIJAKGGusSHcFnHMA0GCS...', );
That's it!
If you have followed all the instructions visit
http://192.168.33.99/simplesaml/module.php/core/authenticate.php.
You'll see our authentication source (molanco-authentication) and our SP(openidp) which will be authenticated against the molanco-authentication source (IdP). Note: You could use another Server/SAML installation to have the SPs and IdPs in their own environment. For testing purposes, having the SP and IdP is enough.
Click on the SP openidp and select one of the IdPs added to this SAML installation. In our case it will appear as the only one we have added into metadata/saml20-idp-remote.php
. For each IdP you add you will be adding one more option into the selectlist below.
Note: When working with enterprise clients, sometimes you don't really want to let them know that you are working with each other (each one of them will appear in the above list). The idea behind the Drupal module multiple_idp_simplesamlphp is that you want to:
- Provide customers a seamless deeplinking integration.
- Provide SLO.
- Use OOP practices.
- Use a different uniqueid per customer. Customers may want to use an employeeId, a random number, an SSN, etc.
- Use different attributes from different customers.
- Not use a proxy to prevent the above selectlist from appearing to redirect users to their IdP. OpenContext is an example of a third party proxy. Here's a use case
- Improve the UX for customers. If a customer wants to authenticate with your website they don't have to select their own company from a selectlist which is not Adhoc.
- Use Drupal 7.
Use admin1:admin1 or admin2:admin2 as Username:Password. Here is when the module UserPass kicks in.
You'll see two amazing attributes
Really, that's it! You are ready to test and play with SSO.
Updating Vagrant box configuration
Based on the above configurations, you can enjoy a new git release (in case you were following the Vagrant box article). Download it and run it!
$ vagrant up
Simplesamlphp_auth & multiple_idp_simplesamlphp
Based on the Drupal module instructions, at this point we have done the following steps:
Installation Overview
Install SimpleSAMLphpConfigure SimpleSAMLphp as a Service ProviderInstall Drupal (if you haven't already)- Install simplesamlphp_auth module
- Configure simplesamlphp_auth module
- Activate the simplesamlphp_auth module
Missing: Configure SimpleSAMLphp as an Identity Provider
TO DOs
Add configuration to the Vagrant box and create a new release- Generate certificates in the Vagrant configuration and generate metadata dynamically
- Connect SAML (simpleSAMLphp) with Drupal 7, simplesaml_php and multiple_idp_simplesamlphp
- Connect SAML (simpleSAMLphp) with Drupal 8 and simplesaml_php