How to implement Single Sign-On

For other folks who run into this, I wanted to share some interesting details;

  • I would recommend staying away from the plugins developed by the “miniOrange” company. (Including the one referenced by that guide above.) They may work well (I don’t really know) but I found their sales strategy of publishing freeware modules and documentation mixed in with Drupal’s - generally free - ecosystem, disingenuous.
  • Instead, consider the openid_connect module and possibly some of the plugins that extend it.

Here’s what I did to set up farmOS to authenticate with Keycloak;

Module installation

composer require 'drupal/openid_connect:^1.4'
drush en openid_connect

composer require 'drupal/keycloak:^1.8'
drush en keycloak

Keycloak Configuration

Groups

Create groups for each of the roles in farmOS. farmos_manager, farmos_viewer, etc.

Client / Client Groups Mapper

Configure a new OAuth client in Keycloak and add a custom groups mapper under its dedicated client scope;

image

Don’t forget to copy the client secret from the credentials tab for the next step…

farmOS configuration

Under the OpenID Connect configuration at https://farmos.test/admin/config/services/openid-connect;

Or via drush;

drush config:set -y --input-format=yaml openid_connect.settings ? "
always_save_userinfo: true
connect_existing_users: true
override_registration_settings: true
user_login_display: replace
userinfo_mappings:
  timezone: zoneinfo
"

drush config:set -y --input-format=yaml openid_connect.settings.keycloak ? "
enabled: true
settings:
  client_id: farmos
  client_secret: ERAvaJhmFq6N8okacpIBaTrDMBl2ADLp
  keycloak_base: 'https://login.farmos.test'
  keycloak_realm: kirchoff_farm
  userinfo_update_email: true
  keycloak_groups:
    enabled: true
    claim_name: groups
    split_groups: false
    split_groups_limit: '0'
    rules:
      -
        id: 3c128a59-f2ce-463b-9e67-8d5b6516116e
        role: farm_manager
        action: add
        operation: regex
        pattern: farmos_manager
        case_sensitive: false
        weight: 0
        enabled: true
      -
        id: ecfe635f-d2e5-4e6c-8336-f1ab90f17270
        role: farm_manager
        action: remove
        operation: not_regex
        pattern: farmos_manager
        case_sensitive: false
        weight: 0
        enabled: true
      -
        id: fce61742-011c-46c2-b7b6-1b372fec3321
        role: farm_worker
        action: add
        operation: regex
        pattern: farmos_worker
        case_sensitive: false
        weight: 0
        enabled: true
      -
        id: 6bb6d978-9c23-477b-8b04-6b95391ac931
        role: farm_worker
        action: remove
        operation: not_regex
        pattern: farmos_worker
        case_sensitive: false
        weight: 0
        enabled: true
      -
        id: 5e1aa944-d04e-42f0-b13a-8b15dbe480de
        role: farm_viewer
        action: add
        operation: regex
        pattern: farmos_viewer
        case_sensitive: false
        weight: 0
        enabled: true
      -
        id: 911a05cf-bfc2-4030-893c-e0963b9e41c9
        role: farm_viewer
        action: remove
        operation: not_regex
        pattern: farmos_viewer
        case_sensitive: false
        weight: 0
        enabled: true
  keycloak_sso: true
  keycloak_sign_out: true
  check_session:
    interval: 2
  redirect_url: ''
  keycloak_i18n_enabled: false
  check_session_enabled: 0
  keycloak_groups_enabled: 0"

Clear Cache

The OpenID Connect module doesn’t seem to invalidate the login page cache correctly so a cache rebuild is needed before you’ll see the changes on the login page.

drush cr

/403 Login Issue

There’s an issue where logins will (almost) always end up on a access denied page upon successful login. https://www.drupal.org/project/farm/issues/3455977

The work-around is to install the r4032login module that makes all the logins occur via the /user/login page.

composer require 'drupal/r4032login:^2.2'
drush en r4032login

farmos.test note

I’m using the domains login.farmos.test & farmos.test with self-signed certificates so I needed to configure the root CA so that Drupal could make requests directly to Keycloak over https. This isn’t needed in production with real certificates of course.

php.ini

[curl]
curl.cainfo = "/localRootCA.pem"

docker-compose.yml

...
  www:
    ...
    volumes:
      ...
      - './devcerts/rootCA.pem:/localRootCA.pem'
...

Result

image

4 Likes