Granite Construction Drupal Case Study

Posted by Third & Grove - 11 Jan 2017 at 08:00 UTC
Granite Construction Drupal Case Study antonella Wed, 01/11/2017 - 03:00

Drupal Modules: The One Percent — Trash (video tutorial)

Posted by Drupal Modules: The One Percent - 11 Jan 2017 at 03:04 UTC
Drupal Modules: The One Percent — Trash (video tutorial) Project page screenshot NonProfit Tue, 01/10/2017 - 21:04 Episode 13

Here is where we bring awareness to Drupal modules running on less than 1% of reporting sites. Today we'll investigate Trash, a module where deleted content entities are sent to a bin where they can later be reenabled or permanently removed.

Close enough for a side project - how to know when things are good enough

Posted by Red Route - 10 Jan 2017 at 22:05 UTC

Once upon a time, before I became a web developer, I worked doing sound and light for events. Like web development, the hours tend to be long, and the work tends to attract anti-social oddballs. Unlike web development, you deal with rock stars. Like most professions, it’s full of jargon and in-jokes. One of the phrases in common usage in that industry was “close enough for rock and roll”. Depending on who you were talking to, it might have been jazz rather than rock and roll, but you get the idea. It isn’t too far away from the notion previously popularised by Voltaire: “Perfect is the enemy of good”.

Another formulation of the same idea was expressed slightly more succinctly (and less politely) on the T-shirt shown in the photo attached to this blog post. It was designed by and for my old student union stage crew. While the T-shirt encapsulates a lot of the attitude of the team, it would be a mistake to imagine that we were sloppy. As I’ve written before, we were unpaid, but we certainly weren’t amateurs. That volunteer crew probably had as high a level of professionalism as any team I’ve been a part of. The point was that we cared about the right things, and there comes a point where you have to accept that things are as good as they are realistically going to get.

There’s a point where it just isn’t worth putting in more effort before launch. You’ve done as much as you can, and you’re proving the law of diminishing returns, or the Pareto principle. Besides, if you carry on fixing things, you’ll end up delaying your launch. If you’re getting ready to put on a show, there's a point where you have to open the doors, whether or not things are 100% ready. There are people outside who have bought tickets. They don’t want to wait while you mess about with your final preparations. They’re here to see the show, and their idea of perfection is very likely to be different from yours.

In events, these people are (somewhat dismissively) called ‘punters’, and they don’t notice the same things that you do. Unless they’re in the business themselves, their perception of the event is likely to be very different to yours. Working on stage crew, I’ve cobbled things together with gaffa tape and crossed my fingers, and the show has turned out fantastically well. As a musician, I’ve done shows that I thought were riddled with mistakes, and people in the audience told me it was the best gig they’d seen us play. Punters don’t go to gigs for technically competent sound or lighting, or flawless performances - they go because they want to have a good time. Things are never as shiny backstage as they are front of house.

Similarly, as a developer, I’ve built sites that have won awards, although the code made me cringe. From a technical point of view, you may not be proud of the code or the architecture underlying a website, but that’s not what people are here for. They are visiting your website for the content, or some of the interactivity that it provides. Most sites are not perfect, but they don’t need to be.

There are certain areas where you should never cut corners. In events, that’s things like rigging lights from the ceiling - you have to make sure that they won’t fall on anyone’s head. In development, it’s in security - you have to make sure that people’s data is safe. If there’s a chance people might get hurt, there’s no excuse for sloppiness. But in most areas of most projects, you’re never going to get things perfect - you need to know what’s good enough.

I’ve been working on my own current side project (the redesign and Drupal 8 upgrade of an art gallery listings site) for a while now, in between the day job and family life. Just before Christmas, I still had quite a few tasks left on my board, but having read an article by Ben Roux, I knew that I needed to get the thing live, sooner rather than later. This is the great thing about side projects - there's something marvellously liberating being able to just make that decision for myself, without consultation with clients or stakeholders.

The great thing about putting your work out there on the web is that publishing improvements is trivial. I’ve defined my minimum viable redesign, so I can iterate and improve after launch, even though some of the functionality from the old Drupal 6 version isn’t ready. I could keep polishing and polishing, but it’s better to put it out there, and fix things later. Besides, I’m pretty confident that the new design is better than the old one, in spite of a few rough edges. Chances are, I’m the only person who will pick up on most of the problems with the site.

On the other hand, this means that nothing is ever finished. One of the things I loved about working in events was that there was a clear beginning, middle and end. We would start with an empty room and a full truck. We would unpack the truck, and fill the room with gear. Then we would put on a show. After the show, we’d pack up the gear and put it back into the truck. Then the truck would drive to the next venue, and we could (usually) go home with the satisfaction of a job well done.

With web development, it’s more like endlessly pushing a boulder up a hill. After putting a site live, there’s no great moment of triumph. If we take the analogy of a concert, it’s more like opening the doors and letting the punters in. Unless it’s a short-lived marketing site, the only time you ever take a website down and pack everything away is if the business has failed. There are always things to improve. I could keep adding features, or tweaking the design, or improving performance forever. But what value would it add? Besides, it’s a side project, and I’ve got other things to do.

Tags:  The Gallery Guide Drupal Drupal 8 work All tags

Uninstall Drupal 8 modules that includes default configuration

Posted by John Svensson - 10 Jan 2017 at 22:02 UTC

In our modules we can include default configuration to ship content types, views, vocabularies on install. If we try to reinstall the module, we'll get an error. Let's take a look at why and how we can solve it.

Unable to install … already exist in active configuration

During uninstall the configuration is not removed because it has no connection to the module itself and thus we get the error because Drupal modules may not replace active configuration. The reason for that is to prevent configuration losses.

We can move all the configuration to config/optional rather than config/install which basically means that configuration that does not exists will be installed and the existing one will be ignored. If we do this we can reinstall the module.

So, if we want the configuration to remain active we've already solved the problem, but if we don't want that, we want the module to remove all configuration and contents its provided we'll need to look at another solution.

Let's take a look at the Article content type that is created when using the Standard distribution on installing Drupal.

node.type.article.yml

langcode: en  
status: true  
dependencies: {  }  
name: Article  
type: article  
description: 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.'  
help: ''  
new_revision: true  
preview_mode: 1  
display_submitted: true  

field.field.node.article.body.yml

langcode: en  
status: true  
dependencies:  
  config:
    - field.storage.node.body
    - node.type.article
  module:
    - text
id: node.article.body  
field_name: body  
entity_type: node  
bundle: article  
label: Body  
description: ''  
required: false  
translatable: true  
default_value: {  }  
default_value_callback: ''  
settings:  
  display_summary: true
field_type: text_with_summary  

If we delete the content type, we can find out that the field instance body on the content type has been removed. First we actually see that the configuration will be removed when confirming the deletion of the content type, but also by looking in the database in the config table where active configuration is stored. It's gone.

The reason it's deleted is because it has an dependency on the node.type.article.yml configuration as we can see:

dependencies:  
  config:
    - field.storage.node.body
    - node.type.article
  module:
    - text

So what we need to do to make sure the content type we create when installing or module, that it's configuration uses our module as an dependency. So let's take a look at how we can do that:

Let's imagine we have a custom_event module that creates a event content type.

node.type.event.yml

langcode: en  
status: true  
dependencies:  
  enforced:
    module:
      - custom_event
third_party_settings: {}  
name: Event  
type: event  
description: 'Event'  
help: ''  
new_revision: true  
preview_mode: 1  
display_submitted: false  

The dependencies-part is the interesting one:

dependencies:  
    enforced:
        module:
            - custom_event

We have defined a custom_event module, in that module we have some exported configuration files in the config/install folder. We update the node.type.event.yml configuration file to have our module as an dependency. Now when we uninstall the module, the content type will be removed.

We also have to do this for our views, taxonomy, and field storages, or pretty much any configuration entity we provide configuration for. We don't have to worry about field instances, as we saw above those are dependent on the content type itself, but field storages on the other hand does not depend on a content type because you can reuse fields on multiple of those.

So, just add the module as an dependency and you're good to go, here's an example on a field storage field_image

field.storage.node.field_image.yml

langcode: en  
status: true  
dependencies:  
  enforced:
    module:
      - custom_event
  module:
    - file
    - image
    - node
id: node.field_image  
field_name: field_image  
entity_type: node  
type: image  
settings:  
  uri_scheme: public
  default_image:
    uuid: null
    alt: ''
    title: ''
    width: null
    height: null
  target_type: file
  display_field: false
  display_default: false
module: image  
locked: false  
cardinality: 1  
translatable: true  
indexes:  
  target_id:
    - target_id
persist_with_no_fields: false  
custom_storage: false  

Add a custom view mode to an entity

Posted by fluffy.pro. Drupal Developer's blog - 10 Jan 2017 at 21:09 UTC
Drupal 7 offers a mechanism to render entities which called view mode. For example you can set up how your entity will look as a full page or as a teaser. By default Drupal provides only two modes for node entity (default and teaser) and one default mode for taxonomy term and user entities. But you can easily add your custom view mode.

First option is setup display suite module. It's powerfull and provides a lot of features like a layout for entity that can be set up from admin UI. But if you need just to add a view mode to an entity and don't need any other functionality you can do it manually.

In this example we will add a new view mode to a node entity:

Now clear the cache and you will get a new view mode.








Basically that's all. You can set up fields formatters, weights and etc. But you might want to assign a specific template for nodes per view mode. Well it's not hard to do. Just define a hook_preprocess_node in theme's template.php file:

Then define node--node-type--view-mode.tpl.php template in your theme folder and provide needed markup there. I suggest to get the default markup from node.tpl.php file and modify it. Clear the cache once again and you will get a rendered through defined template node.

Key notes:

The ABC's of Drupal: Camp, CLI, CMI

Posted by FFW Agency - 10 Jan 2017 at 19:46 UTC
The ABC's of Drupal: Camp, CLI, CMI Ray Saltini Tue, 01/10/2017 - 19:46

For anyone who's ever looked up a definition of a Drupal term and been left wondering what it all means, here are some practical real world explanations you can use to navigate the Drupalverse. Watch this space and use comments to send us your feedback and requests.

Camp 

A camp is a gathering of Drupal experts and other interested humans set up to share best practices, emerging trends and other information. Camps are usually free or low cost and may be organized over one or several days. They are an excellent way to become familiar with the Drupal community and Drupal practices. 

Camps can be found all over the globe. Some are big, some are small, but regardless of size, beginners are always welcome. Many camps offer high-quality, paid trainings taught by leading Drupalists who are experienced in specific areas such as module development, theming or project management. 

Drupal camps are generally built around a series sessions, which are 45 to 90 minute presentations by Drupalists that cover specific topics, themes, or ideas. Most camps organize sessions to cover a variety of topics and experience level so that all attendees get to enjoy great content. Many camps will also organize contribution sprints on a subsequent day, where attendees write code for the Drupal project. 

Sprints are a great way to get more people contributing back to the Drupal project and also a great way to enable regular committers to work more collaboratively and effectively together around a specific set of issues. Visit Drupal.org for info on upcoming events and also Drupical.com a very handy aggregator of Drupal meet ups, camps and conferences.  

(FFW is very active in the camps scenes in the cities where we have offices. If you'd like to check out a Drupal Camp for yourself and want to know if FFW will be there, check out our events page, which lists out which upcoming camps we plan to attend.)

CLI: Command Line Interface

CLI stands for Command Line Interface, which can mean either the Drupal shell program (Drush) or the Symfony-based Drupal Console program. Configuration that occurs via a Drupal graphical user interface can often be performed much more effectively at the command line. 

Drush (rhymes with “crush”) is a mainstay of Drupal configuration and is well known by any developer who’s worth their salt. Drush refers to ‘Drupal Shell’, and is a shell-based software that allows users to administer Drupal sites of all versions from the command line. The other CLI, Drupal Console, was developed specifically for Drupal 8 and is used as a shell program to learn Drupal 8 development, configure Drupal sites, create custom module and theme scaffolding and debug custom code. 

A handy tip from Ray: If someone tries to get you in a conversation about which CLI is better or why we should only have one, it’s best to shrug your shoulders and walk away quietly.  

CMI: Configuration Management Initiative

The Configuration Management Initiative began as a Drupal 8 configuration effort. The goal of CMI was to strengthen Drupal’s configuration workflows. It was also built to mitigate potential roadblocks and collisions in production websites with user generated content that were also undergoing active development.

The main challenge for the CMI was to create a method of saving, versioning, reverting and making portable the changes made to a site’s configuration settings. The initiative lead to fundamental changes in how Drupal classifies and handles configuration data, and laid the foundation for significantly improved development workflows in Drupal 8. CMI is just another reason why you should be developing your next project using Drupal 8. 

To learn more about the unique nature of Drupal, download our Ebook: 10 Drupal Project Pitfalls to Avoid. This eBook has compiled a list of lessons we’ve learned in 15+ years of delivering digital solutions to some of the most recognizable brands in the world. 

Download the Ebook

Drupal word cloud Tagged with Comments

Prominent Midwest Business School

Posted by Palantir - 10 Jan 2017 at 19:35 UTC
Prominent Midwest Business School Illustration from client publicationbrandt Tue, 01/10/2017 - 13:35 Visibility of Research and Ideas Through a Beautiful Design

A highly customizable layout to showcase our client's content.

Highlights
  • Highly customizable layout
  • A strong visual hierarchy punctuated with thoughtful typographic details  
  • Robust tagging and taxonomy for showcasing content

We want to make your project a success.

Let's Chat.

One of the oldest business schools in the country with a worldwide network of over 50,000 alumni, our client is one of the top-ranked business schools in the world. With a reputation for new ideas and research, it needs its online presence to reflect its bold, innovative approach to business education.

Our client’s approach to learning is to, “constantly question, test ideas, and seek proof,” which leads to new ideas and innovative solutions within business. Beyond the classroom, this approach empowers thought leaders and analytical minds to shape the future through deeper analysis and discovery.

In order to create greater visibility of the school’s research and ideas, the school publishes digital and print publications that give insight to business leaders and policymakers who can act upon those ideas. The publications help convey the concepts and research findings generated by the school, as well as by academics outside the school, via articles, infographics, charts, videos, and other devices.

Since both publications were due for an upgrade, our client decided to update its web presence and quarterly print magazine at the same time. With our client having already partnered with another firm to complete the magazine design, Palantir was brought in to design and develop the website in a way that provided cohesion between the two mediums.

Goals and Direction

Because the publication’s previous site was outdated and not optimized for mobile devices, the overall performance was less than ideal, with long loading times causing problems on tablets and smartphones. Additionally, the hierarchy on the old site needed some rethinking: the site was difficult to navigate, with limitations on how articles and videos could be connected, since visitors couldn’t easily or effectively filter or search the contents of the site.

The primary high-level goals for the redesign were to:

  • Move the site to Drupal, which allowed for increased community support and more flexibility in tools that could be incorporated
  • Provide an experience that demonstrated the depth of content from the publication
  • Optimize content search and social visibility
  • Provide a flexible platform that would evolve as the content evolved
  • Highlight visuals and alternative story formats
  • Leverage content featuring the business school’s high-profile faculty

To accomplish the majority of these goals, a well-planned content strategy was required. The new site needed the ability to display content in a variety of ways in order to make it digestible and actionable for readers. All content had to be easily sharable and optimized for the greatest possibility of distribution. Lastly once readers found content they wanted, related content should surface as well.

To support the content strategy, site editors needed the power to elevate content connections and relations through a strong visual design that offered flexibility, and with hierarchy that made sure news matched what visitors were looking for. They also required options on how to best showcase content, as well as the ability to include multiple storytelling mechanisms.

Related content displayed in a browser and mobileExamples of how related content is displayed in both desktop and mobile views while preserving typographic details.

Site Focus

Once goals were outlined, Palantir worked to create a solid content strategy for the site. Taxonomy and tagging were addressed, and a new information architecture was put in place in order to make sure content was being seen and surfaced at the right time. After the initial strategy work was completed, it was decided to focus the work in two key areas:

  • Increase the number of pages during each visit. Prior to the redesign, a large percentage of visitors were coming in from search and social for a single article and then leaving before accessing any more articles, videos, or graphics. The former content management system made tying in related content difficult, so attention was given to each step of the process to make sure that related content could be easily surfaced by editors or by the system based on tagging. A goal was to give visitors more of the type of content they were looking for.
  • Improve number of visits per month. As important as it is to make navigating the site better, ensuring that visitors could find the content more easily was a key improvement that was needed for the site. As part of that, the site required better metadata for search and social optimization.
Style tileStyle tile: Playful/Colorful/ProgressiveStyle tileStyle tile: Dynamic/Modern/Bright

The design of the site was critical to achieving the goals, and we were given latitude to push the boundaries of the existing brand standards in order to give the magazine a distinctive look through color and typography. Our design team expanded the existing brand signals from our client in order to create style tiles to represent the general mood, typography, and colors recommended for the new site. With the variations in image treatment, typography, color palette, and button/quote designs, each style tile worked to capture a specific voice and personality for the magazine. This allowed us to quickly gauge how our client wanted to present itself to the world prior to starting formal layouts.

Once the final direction was chosen, we concentrated next on wireframing the pages so we could marry the functionality with the intended hierarchy and ensure that the revised content strategy was working as efficiently and powerfully as possible. Given that users spent the majority of time on those pages, individual article pages were given particular emphasis in wireframing, to ensure users would be enticed to explore further into the site.

In the layout phase, typography was given special attention, with drop-caps and call-out quotes being implemented to keep a print feel and break up a sea of gray text for long articles. This approach was particularly necessary on the mobile view, allowing the content to take center stage without losing any of the design details. Sharing on social media was also accounted for, with shorter quotes having their own dedicated sharing buttons. Additionally, the wealth of artwork provided by the school’s internal team created exciting opportunities for our design team on all applicable articles.

While not always the entry point for users, the homepage design needed to be as flexible as possible. Not only did we have to account for the hierarchy of stories and surface related content in the right way, but to allow for multiple types of content to be displayed while balancing related articles and email newsletter sign-up forms.

Homepage layoutsExamples of how the homepage can be customized to promote specific sections of content.  

The Results

In the end, our client received a beautiful design that showcases the content well, and provides easy access to related content. Back-end editors are happy with the improved formatting and editing ability, with one editor saying, “it’s not even comparable to our previous site.” Our designs introduced new ways of visually displaying a wealth of content and helped push innovation for the magazine redesign. The print designers were able to apply our design signals to the associated print piece, creating a strong cohesion across all collateral to enhance the school’s brand.

The variety offered by the new homepage design supported the goal of increasing the page views, providing more opportunities to entice people to continue their experience, with connections between different articles and videos. With much of the greater University on Drupal, the move to Drupal also allowed the staff increased support within the school community. The flexibility of the modular design and build allowed staff to control the process and to be able to leverage important research to audiences and policymakers for years to come.

Content collapsed into mobile viewsContent collapsed into mobile views.

 

We want to make your project a success.

Let's Chat. Drupal

Services

strategy design development

UX for Content Editors & Administrators

Posted by Fuse Interactive - 10 Jan 2017 at 18:44 UTC

User Experience as it relates to Content Management Systems tends to overlook its most important users: Content Editors & Administrators.

DrupalEasy Podcast 189 - BACnet to the Future (David Thompson - Energy and Drupal)

Posted by DrupalEasy - 10 Jan 2017 at 14:20 UTC

Direct .mp3 file download.

David Thompson (dbt102), consultant with Function 1, and maintainer of the BACnet and AppCtrl modules (used for building energy management) joins Mike on this first podcast of 2017.

Interview DrupalEasy News Three Stories Sponsors Picks of the Week Upcoming Events Follow us on Twitter Five Questions (answers only)
  1. Bikram Yoga
  2. BACnet advanced workstation with Web Control
  3. Presenting at DrupalCon
  4. Emu
  5. Understanding the value of CCK
Intro Music Subscribe

Subscribe to our podcast on iTunes, Google Play or Miro. Listen to our podcast on Stitcher.

If you'd like to leave us a voicemail, call 321-396-2340. Please keep in mind that we might play your voicemail during one of our future podcasts. Feel free to call in with suggestions, rants, questions, or corrections. If you'd rather just send us an email, please use our contact page.

SAML ADFS authentication in Drupal

Posted by Code Enigma - 10 Jan 2017 at 13:24 UTC
SAML ADFS authentication in Drupal Language English Return to Blog SAML ADFS authentication in Drupal

Drupal as consumer/SP, ADFS as IdP

Photo of Pascal MorinTue, 2017-01-10 13:24By pascal

We'll try to cover the needed step to authenticate (and create if need) Drupal 7 users against an external Active Directory Federation server, using SimpleSAMLphp and the simplesamlphp_auth module.

Examples are given for a Debian server, using Nginx and php-fpm, but most of the configuration would be similar for other setups, and except for the application integration part, the SimpleSAML setup part should apply to any php integration.

Assumptions

We'll assume that:

Dependencies

We'll use memcache to store user sessions (although you can use a MySQL-like database instead), which is done through the php-memcache extension (NOT php-memcached):

sudo apt-get install memcached

sudo apt-get install php5-memcache

Once again, in case you read too fast, php-memcache, NOT php-memcached !

1. Nginx configuration: accessing SimpleSAML library through the web

Given that SAML is based on redirects, the first thing you'd need to do is being able to access the library over HTTPS.

1.1. Install the library

Download the library from https://simplesamlphp.org/download and extract it in Drupal's library folder, so it ends up under sites/all/libraries/simplesamlphp-1.14.8 in the repo (that will match /var/www/drupal-sp.master/www//sites/all/libraries/simplesamlphp-1.14.8 once deployed on the server).

1.2. Amend Nginx' fastcgi configuration

We need to add a line to the /etc/nginx/fastcgi_params file so it supports path_info (in short, paths in the form of file.php/parameter1/parameter2). Instead of amending the default one, we took the view of duplicating it and amending the copy instead:

sudo cp /etc/nginx/fastcgi_params /etc/nginx/fastcgi_params_path_info

and add the following at the end: "fastcgi_param PATH_INFO $fastcgi_path_info;"

The resulting file should now look like:

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;
 
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
 
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
 
fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;
 
fastcgi_param  HTTPS              $https if_not_empty;
 
fastcgi_param  HTTP_PROXY         "";
 
fastcgi_param PATH_INFO $fastcgi_path_info;
 
 
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

1.3 Setup the vhost

While it is possible to use a different subdomain for your application and the SimpleSAML library (look at 'session.cookie.domain' on SimpleSAML side and '$cookie_domain' on Drupal side), the simplest and most common approach is to have both under the same domain. Typically, our Drupal installation being at https://drupal-sp.example.com/, we would make the library accessible at https://drupal-sp.example.com/simplesaml/. Note the 'simplesaml' location has been chosen for simplicity of the example, but it could be set to anything, https://drupal-sp.example.com/auth/, https://drupal-sp.example.com/whatever/, ...

What we need to do is setting up an alias for our /simplesaml location to the library webroot on the filesystem at /var/www/drupal-sp.master/www/sites/all/libraries/simplesamlphp-1.14.8/www. The resulting vhost file (trimmed non-relevant parts) would be similar to:

server {
        server_name drupal-sp.example.com/;
        listen 443 ssl;
        # DRUPAL_ROOT
        root /var/www/drupal-sp.master/www;
        fastcgi_param HTTPS on;
        #### BEGIN SAML specific config ####
        # We could use any alias, as long it matches the config.php of SimpleSAML.
        location /simplesaml {
          # Point to our library folder webroot.
          alias /var/www/drupal-sp.master/www/sites/all/libraries/simplesamlphp-1.14.8/www;
          location ~ ^(?<prefix>/simplesaml)(?<phpfile>.+?\.php)(?<pathinfo>/.*)?$ {
            fastcgi_split_path_info ^(.+?\.php)(/.+)$;
            fastcgi_pass             127.0.0.1:9000;
            fastcgi_index index.php;
            # Note we include the fastcgi config copied and modified above.
            include fastcgi_params_path_info;
            fastcgi_param SCRIPT_FILENAME $document_root$phpfile;
            fastcgi_param PATH_INFO $pathinfo if_not_empty;
         }
         # This looks extremly weird, and it is. Workaround a NGINX bug. @see https://trac.nginx.org/nginx/ticket/97
         # Without this the assets (js/css/img) won't be served.
         location ~ ^(?<prefix>/simplesaml/resources/)(?<assetfile>.+?\.(js|css|png|jpg|jpeg|gif|ico))$ {
           return 301 $scheme://$server_name/sites/all/libraries/simplesamlphp-1.14.8/www/resources/$assetfile;
         }
        }
        #### END SAML specific config ####
        ## Rest of your app specific directives.
}
2. SimpleSAML configuration

2.1 config.php

This is where the main "global" configuration directives reside, and it is located under the "config" folder of the library. Most of the default are fine as is, we are mainly going to set:

  • the main path
  • the memcache settings
  • the debug mode

The resulting file would end up with the following options:

 

<?php
 
/*
 * The configuration of SimpleSAMLphp
 * 
 */
 
$config = array(
  /**
   * Full url to the library. Trailing slash is needed.
   */
  'baseurlpath' => 'https://drupal-sp.example.com/simplesaml/',
  /**
   * Debug data. Turn all that to FALSE on prod.
   */
  'debug' => TRUE,
  'showerrors' => TRUE,
  'errorreporting' => TRUE,
  /**
   * Admin access, do not enable on prod.
   */
  'auth.adminpassword' => 'MYPASSWORD',
  'admin.protectindexpage' => FALSE,
  'admin.protectmetadata' => FALSE,
  /**
   * This is a secret salt used by SimpleSAMLphp when it needs to generate a secure hash
   * of a value. It must be changed from its default value to a secret value. The value of
   * 'secretsalt' can be any valid string of any length.
   *
   * A possible way to generate a random salt is by running the following command from a unix shell:
   * tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo
   */
  'secretsalt' => 'omqczwt6klfdn244787098jqlfjdsql',
  /*
   * Some information about the technical persons running this installation.
   * The email address will be used as the recipient address for error reports, and
   * also as the technical contact in generated metadata.
   */
  'technicalcontact_name' => 'Administrator',
  'technicalcontact_email' => 'na@example.org',
  /**
   * We want debugging on while setting our install up.
   */
  'logging.level' => SimpleSAML_Logger::DEBUG,
  'logging.handler' => 'syslog',
  /**
   * Sessions will be held in memcache.
   */
  'store.type' => 'memcache',
  'memcache_store.servers' => array(
    array(
      array('hostname' => 'localhost'),
    ),
  ),
);

At this point, you should be able to reach https://drupal-sp.example.com/simplesaml/ and login as 'Admin' using the local SimpleSAML authentication mechanism. Check the "configuration" tab to access basic sanity checks on your config.

2.3 authsources.php

We're now ready to define our new authentication source in the config/authsources.php file, that holds an array of all available authentication sources. You'll notice there's already an "admin" one, which is the default local one defined by the SimpleSAML php library.

We assume that nothing has yet been created on the ADFS side (we'll do that at a later step), if that's not your case, you should match the entityID with the one provided to you.

<?php
 
$config = array(
  'admin' => array(
    // Default local auth source.
    'core:AdminPassword',
  ),
  'example-drupal-sp' => array(
    // Type of auth source.
    'saml:SP',
    // Unique identifier of your SP.
    // This can be set to anything, as long as no other SP use it on the IDP already.
    'entityID' => 'urn:drupal:example',
    // IDP url identifier. A mean of getting the precise url is given later (@todo link)
    'idp' => 'http://adfs-idp.example.com/adfs/services/trust',
    // This must be explicitely set to NULL, we rely on metadata.
    'NameIDPolicy' => NULL,
    // These are the SP-side certificate, that we will need to generate.
    // The location is relative to the 'cert' directive specified in the
    // config.php file.
    'privatekey' => 'saml.pem',
    'certificate' => 'saml.crt',
    // Enforce signing of redirections, using our certificate.
    'sign.logout' => TRUE,
    'redirect.sign' => TRUE,
    'assertion.encryption' => TRUE,
    // Enforce use of sha256.
    'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
  ),
);

If you navigate to the "Authentication" tab > "Test configured authentication sources" within the /simplesaml admin interface, you should now see your new source appear as "example-drupal-sp". Don't try yet to use it, it will just throw exceptions for now !

Certificate generation

We now need to generate the certificates we did specify in the auth source, they will be used to sign our requests. We'll stick with the default location and create them under the "cert" directory of the library.

cd sites/all/libraries/simplesamlphp-1.14.8/cert

openssl req -x509 -sha256 -nodes -days 3652 -newkey rsa:2048 -keyout saml.pem -out saml.crt

2.4 saml20-idp-remote.php

The last piece of information that is needed for the two systems to be able to communicate is the metadata specification, which defines the various endpoints and protocols to use. The ADFS server conveniently exposes those, so we just need to get hold of them, and convert it to php. The federation XML file is usually located under /FederationMetadata/2007-06/FederationMetadata.xml but you can find it out from the ADFS management tool, by expanding "Services" > "Endpoints" and looking at the Metadata section.

In our case we would download "https://adfs-idp.example.com/FederationMetadata/2007-06/FederationMetada...". The next step is to convert it to a php array, with an utility provided by the SimpleSAML library, located at /simplesaml/admin/metadata-converter.php. This will generate 2 php arrays ready to copy paste:

  • saml20-sp-remote: we can ignore this one in our setup, as we are only acting as a Service Provider
  • saml20-idp-remote: this is the data we will need, and we are going to copy/paste it into metadata/saml20-idp-remote.php.

The array key should match the value of what we had specified in our authsources:

authsources.php:

'idp' => 'http://adfs-idp.example.com/adfs/services/trust',

saml20-idp-remote.php

$metadata['http://adfs-idp.example.com/adfs/services/trust'] = array(

If that's not the case, amend your authsource. Pay especially attention to the fact that the idp may identify itself as http://, not https://, even though all requests go through https endpoints.

3. ADFS setup

Now the SP side component is ready, we need to configure the IDP side.

3.1 SP metadata

In the same way our SP needs metadata to know how to talk to the IDP, the ADFS server needs to how to communicate with the SimpleSAML library, and must be provided some metadata. Here again, the SimpleSAML php library helps us a lot by exposing its metadata, ready for the server to consume.

You can obtain this url within the /simplesaml admin section, under the "Federation" tab, by clicking on the "View metadata" link underneath your "example-drupal-sp" source. This will display the actual metadata, along with the dedicated url to obtain it, https://drupal-sp.example.com/simplesaml/module.php/saml/sp/metadata.php... in our case.

3.2 Trust configuration

In the ADFS admin tool on the Windows server, create a new "Relying Party Trust". This should launch a Wizard similar to:

Enter the SP metadata URL (https://drupal-sp.example.com/simplesaml/module.php/saml/sp/metadata.php...) into the "Federation metadata address" field and press next. This should be enough to setup all the needed configuration, even though you will get a notice about some metadata fields being ignored, which you can ignore.

3.3 Claims

These claims serve as mappings between ADFS and SAML "fields", and are accessible trough the "Edit Claim Rules..." entry.

3.3.1 LDAP attributes

Create an "Issuance Transform Rule", of type "Send LDAP Attributes as Claims" with the fields you need to pass back to the SP. Some are preset and defined in the metadata, but you can add custom ones: In this example UPN and Email are using the set schema, while DisplayName is custom: