Turn Drupal 8 into an Identity Provider (continued)

By Ronald van Belzen | December 13, 2017

In a previous blog post I described how to turn a Drupal 8 installation into a Identity Provider (IdP) by configuring SimpleSAMLphp. The configuration files where placed in a subdirectory of the vendor map, which is something you really should not do when you are using Composer to install and update your Drupal installation.

Move the configuration files

When you move these configuration files to another location SimpleSAMLphp should be told about it. For this purpose the environment variable SIMPLESAMLPHP_CONFIG_DIR exists. To my experience the best way to set this variable is in the Apache vhost.conf file. In my case I moved the configuration files to /var/www/drupalvm/drupal/web/sites/default/simplesamlphp:

<VirtualHost *:80>
  ServerName samlvm.dev
  ServerAlias www.samlvm.dev
  DocumentRoot "/var/www/drupalvm/drupal/web"
  Alias /simplesaml "/var/www/drupalvm/drupal/vendor/simplesamlphp/simplesamlphp/www"
  SetEnv SIMPLESAMLPHP_CONFIG_DIR "/var/www/drupalvm/drupal/web/sites/default/simplesamlphp"
  <Directory "/var/www/drupalvm/drupal/web">
    AllowOverride All
    Options -Indexes +FollowSymLinks
    Require all granted
  </Directory>
  <FilesMatch \.php$>
    SetHandler "proxy:fcgi://127.0.0.1:9000"
  </FilesMatch>
</VirtualHost>

The files 'config.php' and 'authsources.php' are placed in this subdirectory (not is a subdirectory ./config of this subdirectory).

In this subdirectory the subdirectories ./cert, ./metadata and ./modules are created. The ./cert subdirectory contains the certificates we created in the previous blog post. The ./metadata subdirectory contains the files 'saml20-idp-hosted.php' and 'saml20-sp-remote.php' that were also created in the previous blog post. The ./modules directory just contains the ./modules/drupalauth subdirectory with the empty file 'default-enable'.

Next we need to tell SimpleSAMLphp where to find the certificates and the metadata in the 'config.php':

$config = array(
    'baseurlpath' => 'simplesaml/',
    'certdir' => dirname(__FILE__) . '/cert/',
    'metadatadir' => dirname(__FILE__) . '/metadata/',
    'loggingdir' => 'log/',
    'datadir' => 'data/',

Override the saml_idp module

In fact I created another module to override the resume functionality of saml_idp. The my_idp info file:

name: My IdP
type: module
description: 'Provides SAML IdP authentication support'
package: Web services
dependencies:
  - saml_idp
core: '8.x'

The routing file 'my_idp.routing.yml' is as follows:

my_idp.resume:
  path: '/my_idp/resume'
  defaults:
    _controller: '\Drupal\my_idp\Resume::resume'
  requirements:
    _method: GET
    _role: 'authenticated'

The controller mentioned in the routing file:

<?php

namespace Drupal\my_idp;

class Resume {
  public function resume() {
    // Drupal attempts to instantiate the called controller class,
    // so this basically acts as a wrapper around the static function.
    \sspmod_myidpauth_Auth_Source_External::resume();
  }
}

The class sspmod_myidpauth_Auth_Source_External extends \sspmod_drupalauth_Auth_Source_External of the saml_idp module. It contains a copy of all code present in sspmod_drupalauth_Auth_Source_External as a starting point. The file name is the same (External.php) as in the saml_idp.

To ensure that this class will be autoloaded the directory, in which this class file resides, is added to the Composer 'composer.json' of the installation in the autoload class map:

    "autoload": {
        "classmap": [
            "scripts/composer/ScriptHandler.php",
            "web/modules/custom/my_idp/src/Auth/Source"
        ]
    },

To use this module one SimpleSAMLphp configurations needs to be changed. The name of the SimpleSAMLphp module used by the module saml_idp is drupalauth, while the my_idp module uses the SimpleSAMLphp module name myidpauth. By replacing the name drupalauth by myidpauth in the configuration we tell SimpleSAMLphp to use the new module and its class sspmod_myidpauth_Auth_Source_External (notice that myidpauth is part of the class name).

The configuration file that needs to be changed is 'authsources.php'.

    'drupal-userpass' => array( 'myidpauth:External'),

We also need to replace the use of drupalauth by myidpauth in the code of the class sspmod_myidpauth_Auth_Source_External (part of 4 $state array key values).

After we have enabled our new module and have run the Composer dump-autoload command we are ready do use and adapt the new class. The main functions that are candidates for adaptation are the functions authenticate() and getUser().

Authenticate() redirects the login to the Drupal login form. For decoupled Drupal that needs to be changed to redirecting to a script page.

getUser() may need to be changed by expanding the number of attributes that need to be passed in the SAML response.

Add new comment