CMS, Uncategorized

Drupal 8 & SimpleSAMLPHP Library

Security Assertion Markup Language (SAML) is an open standard that allows identity providers (IdP) to pass authorization credentials to service providers (SP) [Source]through digitally signed XML documents. SimpleSAMLphp as a service provider will communicate and delegate authentication to an Identity Provider. SimpleSAMLphp can also be configured as an IDP to achieve a federated Single Sign-On environment with a directory of users, a database, an LDAP or a Radius interface. The diagram below demonstrates various components in SAML and how the protocol works.

This blog describes how to configure SSO in a Drupal website using SimpleSAMLphp. SimpleSAMLphp is an award-winning application written in native PHP that deals with authentication. SimpleSAMLphp can be used both as a SAML service provider(SP) as well as the SAML identity provider(IDP).

Installing SimpleSAMLphp application

To configure SAML SP in drupal  simplesamlphp_auth contributed module can be used as follows:

  1. Download simplesamlphp_auth module using composer from the Drupal installation directory.
    composer require drupal/simplesamlphp_auth

    This will also download the SimpleSAMLphp application into the composer vendor folder.

  2. Now create a symlink to the www folder inside SimpleSAMLphp, so that it can be accessed via the web.
    symlink simplesaml vendor/simplesamlphp/simplesamlphp/www
  3. There is required some configurations in the .htaccess file, in order to access the whole SimpleSAMLphp application.  Below code needs to be added to the .htaccess file.
    # For security reasons, deny access to other PHP files on public sites.
    # Note: The following URI conditions are not anchored at the start (^),
    # because Drupal may be located in a subdirectory. To further improve
    # security, you can replace '!/' with '!^/'.
    # Allow access to PHP files in /core (like authorize.php or install.php):
    RewriteCond %{REQUEST_URI} !/core/[^/]*\.php$
    # Allow access to test-specific PHP files:
    RewriteCond %{REQUEST_URI} !/core/modules/system/tests/https?.php
    # Allow access to Statistics module's custom front controller.
    # Copy and adapt this rule to directly execute PHP files in contributed or
    # custom modules or to run another PHP application in the same directory.
    RewriteCond %{REQUEST_URI} !/core/modules/statistics/statistics.php$
    
    # Allow access to simplesamlphp scripts.
    RewriteCond %{REQUEST_URI} !/simplesaml/[^/]*\.php$
    RewriteCond %{REQUEST_URI} !/simplesaml/admin/[^/]*\.php$
    RewriteCond %{REQUEST_URI} !/simplesaml/[^/]*\.php/sanitycheck/[^/]*\.php$
    RewriteCond %{REQUEST_URI} !/simplesaml/[^/]*\.php/saml/[^/]*\.php$
    RewriteCond %{REQUEST_URI} !/simplesaml/[^/]*\.php/saml/sp/[^/]*\.php/default-sp$
    
    # Deny access to any other PHP files that do not match the rules above.
    # Specifically, disallow autoload.php from being served directly.
    RewriteRule "^(.+/.*|autoload)\.php($|/)" - [F]
  4. Now the application can be accessed at http://drupal-local.com/simplesaml, assuming drupal-local.com is the domain of the current Drupal application.

Configuring SimpleSAMLphp as SP

  1. The apache virtual-host file should be now configured to set SIMPLESAMLPHP_CONFIG_DIR environment variable to the theSimpleSAMLphp config directory. Below is the sample.
    <VirtualHost *:80>
        ServerName drupal-local.com
        DocumentRoot "/var/www/html/drupal"
        RewriteEngine On
        SetEnv SIMPLESAMLPHP_CONFIG_DIR /var/www/html/drupal/simplesamlphp/config
  2. Now create a directory SimpleSAMLphp in the docroot of your Drupal application, where configuration and metadata related to SimpleSAMLphp will be stored.
    mkdir -p /var/www/html/drupal/simplesamlphp

    Now copy the SimpleSAMLphp default configuration templates to the newly created directory.

    cp -R vendor/simplesamlphp/simplesamlphp/config simplesamlphp/

    Now adjust the SimpleSAMLphp configurations by making the following changes to the config/config.php file.

    1. Set an administrator password: 

    'auth.adminpassword' => 'setnewpasswordhere',

    2. Set secret salt:

    The command below can be used to generate random string on (some) UNIX systems:

    tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo
    'secretsalt' => 'randombytesinsertedhere',

    3. Configure the SimpleSAMLphp default session handler to Memcache.
    Although SimpleSAMLphp supports phpsession, sql as the session handlers, we will use Memcache as default session handler because the formers fail on load-balanced environments.  Using memcache Sessions can be distributed and replicated among several Memcache servers, enabling both load-balancing and fail-over. Make sure the Memcache server is configured and running before making this configuration.

    'store.type' => 'memcache',
  3. Copy the default metadata templates to the metadata folder. This is where the metadata are configured to make a bridge between the SP and IDP. We will get into the details in the later part of the blog.
    cp vendor/simplesamlphp/simplesamlphp/metadata-templates simplesamlphp/metadata

    Configure the meatdatadir property in the config/config.php as follows:

    'metadatadir' => '/var/www/html/drupal/simplesamlphp/metadata',

    After doing all the setup above the SimpleSAMLphp application be accessed at http://drupal-local.com/simplesaml.

 

Configuring SimpleSAMLphp as an IdP

SAML Id provider provides user authorization data to the service provider and the authorization source can be a directory of users, a database, an LDAP or a Radius interface, etc. SimpleSAMLphp can also be installed and configured as a SAML identity provider as follows.

  1. Download the most recent release of SimpleSAMLphp from https://simplesamlphp.org/download  and extract it into a directory where you want to install it.
    cd /var/www/html
    tar xzf simplesamlphp-x.y.z.tar.gz
    mv simplesamlphp-x.y.z simplesamlphp
  2. Create a new Apache virtual host so that the application can be accessed via the web.
    <VirtualHost *:80>
        ServerName local.samlidp.com
        DocumentRoot "/var/www/html/samlidp"
        RewriteEngine On
        SetEnv SIMPLESAMLPHP_CONFIG_DIR /var/www/html/samlidp/config
        Alias /simplesaml /var/www/html/samlidp/www
        <Directory /var/www/html/samlidp>
            Options FollowSymLinks MultiViews
            Order deny,allow
            Allow from all
            AllowOverride All
        </Directory>
    </VirtualHost>
  3. As described earlier do the necessary changes to the config/config.php file.
  4. To use SimpleSAMLphp as an Id provider enable the SAML 2.0 id provider functionality by making the changes below to the config/config.php file.

    'enable.saml20-idp' => true,
  5. The next step is to configure the way users authenticate on your IdP. SimpleSamlPhp provides many methods for authenticating users via modules. They can be found under /modules directory. We will use exampleauth:UserPass module as our authentication source.
    1. Enable the module exampleauth:UserPass, by creating an enable file inside the module.

      cd modules/exampleauth
      touch enable
    2. In config/authsources.php configure the authentication as follows:
      'example-userpass' => [
          'exampleauth:UserPass',
      
          // Give the user an option to save their username for future login attempts
          // And when enabled, what should the default be, to save the username or not
          //'remember.username.enabled' => false,
          //'remember.username.checked' => false,
      
          'student:studentpassword' => [
              'uid' => ['student'],
              'eduPersonAffiliation' => ['member', 'student'],
              'email' => 'student@example.com'
          ],
          'employee:employeepassword' => [
              'uid' => ['employee'],
              'eduPersonAffiliation' => ['member', 'employee'],
              'email' => 'employee@example.com'
          ],
      ],
    3. Now the authentication can be verified from the Authentication tab of the application.


    4. Now in the next step, we need to configure Idp. For that SSL self-signed certificate needs to be created in the /cert directory as follows.
      cd cert
      openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out server.crt -keyout server.pem
    5. Now SAML 2.0 IdP needs to be configured by the metadata stored in metadata/saml20-idp-hosted.php. Below is a sample configuration.
      $metadata['__DYNAMIC:1__'] = [
          /*
           * The hostname of the server (VHOST) that will use this SAML entity.
           *
           * Can be '__DEFAULT__', to use this entry by default.
           */
          'host' => '__DEFAULT__',
      
          // X.509 key and certificate. Relative to the cert directory.
          'privatekey' => 'server.pem',
          'certificate' => 'server.crt',
      
          /*
           * Authentication source to use. Must be one that is configured in
           * 'config/authsources.php'.
           */
          'auth' => 'example-userpass',
      ];

      After the above configuration, the Idp can be verified from the Federation tab.

Configuring IDP with the SP

As both the Sp and IDPs are configured successfully, now the Sp needs to know about the Idp, so that it can perform the authorization based on the identities provided by the IDP. This can be achieved by sharing the metadata between the Sp and Idp. 

  1. Copy the IDP metadata in php format from the Federation tab of the application and add it to the metadata/saml20-idp-remote.php file of the service provider application.
  2. In the same way, the service provider metadata needs to be exchanged with the identity provider as well. This can be done by copying the SP metadata and adding to  metadata/saml20-sp-remote.php file of the Idp application.
  3. In the last step, the service provider needs to be configured with the IDP name. In the service provider’s config/authsources.php add the Idp name as follows:
    // An authentication source which can authenticate against both SAML 2.0
    // and Shibboleth 1.3 IdPs.
    'default-sp' => [
        'saml:SP',
    
        // The entity ID of this SP.
        // Can be NULL/unset, in which case an entity ID is generated based on the metadata URL.
        'entityID' => null,
    
        // The entity ID of the IdP this SP should contact.
        // Can be NULL/unset, in which case the user will be shown a list of available IdPs.
        'idp' => 'http://local.samlidp.com/simplesaml/saml2/idp/metadata.php',
    
        // The URL to the discovery service.
        // Can be NULL/unset, in which case a builtin discovery service will be used.
        'discoURL' => null,
    ]
    

     

  4. To verify the configuration, click on the Test configured authentication sources link in the Authentication tab of the SP application. Select the configured SP and it will redirect to the Idp application for login. After a successful login, it will redirect back to the SP application and a new session will be configured for the user.

Configure simplesamlphp_auth module

Now that the SP and Idp are configured successfully, we can configure Drupal for SSO. First, enable the simplesamlphp_auth module.

drush en simplesamlphp_auth -y

Go to admin/config/people/simplesamlphp_auth for SimpleSAMLphp Auth Settings and add the Authentication source for the SP(default-sp in our case).

Now in the User info and syncing tab configure the SimpleSAMLphp user attributes required for Drupal authentication.
Now in the Drupal user login page click on Federated login link to login as a user configured in the Idp.

 

Reference:

  1. About SAML: https://www.varonis.com/blog/what-is-saml/
  2. SimpleSAMLPhp installation : https://simplesamlphp.org/docs/stable/simplesamlphp-install
  3. SimpelSAMLPhp as SP: https://simplesamlphp.org/docs/stable/simplesamlphp-sp
  4. SimpeSAMLPhp as IDP: https://simplesamlphp.org/docs/stable/simplesamlphp-idp
  5. Drupal simplesamlphp_auth module: https://www.drupal.org/project/simplesamlphp_auth

About The Author