OpenID Connect Single Sign-on
This is a documentation page for the OpenID Connect Single Sign-on module.
The openid_connect_sso module provides a single sign-on solution based on OpenID Connect.
The OpenID Connect server (central place of login) is a Drupal site running oauth2_server.
The clients are Drupal sites running openid_connect.
After the user's login on the server or logout on any of the network sites, the module starts a redirect chain that visits the SSO script of each site in the network. The SSO script then sets a cookie notifying the parent site of the pending login or logout. When the user visits the actual site, the cookie is read, and the user logged in or out automatically.
This is the same approach used by Google Accounts.
The point of the redirects is to give each site a chance to set a cookie valid for its domain, thus going around the same-origin policy that forbids a site from setting a cookie for another domain. The redirects are fast and unnoticeable, since the SSO script is standalone (no Drupal bootstrap) and only sets the cookie.
Example
Let's say we have four sites:
- The server: server.com
- Client A: clienta.com
- Client B: shop.clientb.com
- Client C: clientc.com
The SSO script is placed in a directory mapped to a subdomain of each site (a.servera.com, a.clienta.com, a.shop.clientb.com, a.clientc.com).
Login flow
- User clicks "Login" on clienta.com.
- The site redirects the user to server.com's login page. The user logs in and is redirected back to clienta.com where the login is completed.
- clienta.com redirects the user to a.clienta.com which begins the login redirect chain. Each site in the chain sets a cookie, noting that the user is logged in via the SSO server.
- a.clienta.com redirects to a.shop.clientb.com.
- a.shop.clienb.com redirects to a.clientc.com
- a.clientc.com returns the user to a.clienta.com
- When the user first visits any other SSO site for the first time, it will detect the cookie set by the SSO script, perform the login flow: redirect to server.com, redirect back to the visited site with an authorization code, and then finally logging the user in.
Logout flow
- User goes to shop.clientb.com, clicks logout.
- That site (shop.clientb.com) logs the user out and redirects to a.shop.clientb.com. This begins the logout redirect chain. Each site sets a logout cookie and then forwards to the next site in the chain.
- a.shop.clientb.com redirects to a.server.com.
- a.server.com redirects to a.clienta.com.
- a.clienta.com redirects to a.clientc.com.
- When the user visits any of the sites in the network (server.com, clienta.com, clientc.com), the logout cookie is detected and logout is performed.
Server setup
- Download and install oauth2_server 7.x-1.x-dev, use the "develop" branch of the required library.
- Make sure that authenticated users have the Use OAuth2 Server permission.
- Go to admin/structure/oauth2-servers and create a server:
- Select the "Use OpenID Connect" checkbox.
- Under "Enabled grant types" select the "Authorization code" checkbox.
- Click the "clients" link for your server, and create a client for each of the client sites:
- Select a client_id and client_secret, you will enter them on the client site.
- As the redirect url enter the url of your site followed by "/openid-connect/generic".
- Select the "Automatically authorize this client" checkbox.
- Enable openid_connect_sso.
- Setup the SSO script.
Note that openid_connect provides OpenID clients, does nothing when enabled on the server. openid_connect_sso_client redirects to the server, and must not be enabled on the server: it causes redirect loops. It is possible to include the server in the chain of sites which are visited on logout, and to do so, go to admin/config/services/openid-connect-sso and enable SSO and add the first script's redirect path, as you do for the client.
Client setup
- Download and install openid_connect (7.x-1.0-beta1 or newer).
- Go to admin/config/services/openid-connect. Enable the Generic client and modify the endpoint urls by replacing example.com with the url of your server.
- Enable openid_connect_sso and openid_connect_sso_client.
- Setup the SSO script (see 'SSO Script Setup' below.
- Add the cache exception to settings.php (see 'Caching' below)
- Go to admin/config/services/openid-connect-sso to setup the SSO process.
- Enable SSO should be checked.
- SSO script URL should point to the location of the sso.php script for the first site that you setup earlier in your $network array (for example, either http://a.firstsite.example.com or https://firstsite.example.com/sso.php). This starts the SSO redirection chain which sets login and logout cookies.
- Cookie domain should almost always be the normal domain of the client site (clientb.example.com). If you have multiple subdomains which serve the same site (for example, a multilingual site with fr.example.com, de.example.com, and es.example.com), you would want to set the cookie domain on each one to the same thing (example.com). A leading dot for the cookie domain can be used, but is not required.
- OpenID Connect client is used to select from the clients that you defined earlier. (usually set to Generic)
SSO Script Setup
You can choose to either have the SSO script in the same directory as your Drupal site (http://yoursite.com/sso.php) or on a subdomain (http://a.yoursite.com).
The subdomain approach allows you to use the same sso.php script for all sites in the network (by mapping all subdomains to the same script on the server). Otherwise the sso.php script needs to be copied to each network site, and the $network array needs to be kept in sync and up to date.
Copy the sso.php script located within the sso directory of the module and edit the $network array as instructed. The $network array can be in any order, in theory.
If you have two different sites sharing the same base domain (for example, site1.example.com and site2.example.com, or subdomain.example.com and example.com), then you should uncomment and enable the $cookie_name_strict = true; setting.
The variable $cookie_name_strict adds the domain name to the cookie name. For example, instead of a cookie named Drupal.visitor.SSOLogout=1, the cookie name will be Drupal.visitor.SSOLogout_www.example.com=1. This ensures that one site (at site.example.com) will not act on the cookie information for another site (at example.com).
Same directory as your Drupal site
Go to admin/config/services/openid-connect-sso and set SSO script URL to, for example, https://clienta.example.com/sso.php.
Copy the sso.php script to your Drupal directory (next to your index.php) file.
Edit the sso.php script and change the $network array as instructed.
Subdomain
Go to admin/config/services/openid-connect-sso and set SSO script URL to, for example, http://a.clienta.example.com.
Copy the sso directory outside of the Drupal modules directory.
Create a subdomain pointing to the sso directory, and set sso.php as the index. Check that your SSO script is available and working at all of the addresses listed in the $network array.
Sample nginx configuration (/etc/nginx/sites-enabled/clienta-sso):
server {
listen 80;
include /etc/nginx/errors.conf;
server_name http://a.clienta.com;
root /data/clienta/docroot/sso;
access_log /data/clienta/logs/access-sso.log;
location / {
index sso.php;
}
# We might not need this?
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS $php_https;
include fastcgi_params;
ssi on;
}
location ~ /\.ht {
deny all;
}
}
Edit the sso.php script and change the $network array as instructed.
On Apache with cPanel, an .htaccess file can be created in the same directory as the sso.php script with, for example:
DirectoryIndex sso.php
Caching
If your client sites have Drupal page caching enabled, you will have to either add these lines to your settings.php:
// Disable the page cache if an SSO login cookie is set.
if (!empty($_COOKIE['Drupal_visitor_SSOLogin'])) {
$conf['cache'] = FALSE;
}
or (preferably) apply this core patch: https://www.drupal.org/project/drupal/issues/322104#comment-9855189
If you use Varnish or another caching solution, you will need to implement similar logic to forward the SSO login/logout cookies and to make sure the page isn't cached if the login cookie is set.
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion