WordPress Plugin: CAS/LDAP Authentication with Redirect
My workplace is implementing a single sign on architecture (SSO) and several of our user facing sites need to provide a means to authenticate those users before allowing them to use the resources, or participate in the discussions on those sites. Partly because of its ease of use and flexibility in customization, we chose WordPress as our CMS of choice for many of these sites. The next step was to integrate all of these sites with our SSO architecture.
The requirements for this plugin were fairly straightforward:
- If a user had been signed in to another of our sites but was not a “registered user” on the WordPress site, create their user with data from the LDAP and log them in to the main page with basic “User” privileges.
- If a user had been signed in to another of our sites and was a “registered user” on the WordPress site, sign them in to the main page with their username.
- If a user had been signed in to another of our sites and was an “Administrator” on the WordPress site, sign them in to the Administrator Dashboard upon signing in.
- Make it an “all-in-one” plugin so that no additional items needed to be downloaded and installed. For this reason, the Jasig PHP CAS client is bundled right into the plugin. (The current version bundled with this plugin is phpCAS 1.3.2)
Since we wanted to be able to redirect users based on their level of authorization, I knew that I would not only need to authenticate each user, but also retrieve the user roles and capabilities appropriately; if we can determine the role of the user, we can potentially expand the plugin to include additional redirects. The added benefit of needing to redirect actually turned out to be a useful notification tool. If we needed a landing page for users to express some vital information, we could change the redirect for registered users to push them to the notification page upon login.
How it works
The plugin takes control of the wp_login() and wp_logout() functions by hooking into them. Both the sign in process and the sign out process are sent to the CAS server. After successfully authenticating, the plugin checks the WordPress instance if the user already exists. If the user exists, it authenticates the user and signs them into the site, redirecting them if necessary. The plugin only determines if a user is an administrator; if not, the user is directed the standard page. If the user does not exist, then the plugin takes advantage of the wp_create_user() function and uses the information it retrieves from the LDAP to create the new user. The lowest level of user (subscriber) is used to create the new user. Once the user has been created, any administrator can adjust the user’s settings to give them access to more of the dashboard.
Setting up an instance
Installation is fairly straightforward if you have the information for your CAS and LDAP servers. To install, follow the instructions below:
- Upload the ZIP archive to your server via “Plugins > Add New > Upload”
- Activate the Plugin from the list of installed plugins
- Go to “Settings > CAS/LDAP Settings” and enter in the information for your servers.
- Important! Set up the redirect options. If you do not set up the redirect options, WP will simply drop the user back onto the login page. And, because the user has been created with a random password, that user will not be able to log in. The simplest option is to use “index.php” as the user redirect as that brings users to the main page of the site, and to use “wp-admin/index.php” for the administrators, as it brings them to the site dashboard.
- Set up the data mapping from the LDAP. This plugin does not have default settings for the username, first and last names, and email fields. In fact, the primary LDAP system at work is somewhat non-standard, so the data mapping was included to allow us to hook this plugin into various LDAP schemas and map those fields to the proper LDAP fields. Note: if you don’t set this up, new users will not be created, and the authentication process will fail. The most common settings are “uid or username” for the username field, “mail” for email, “givenName” for first name, “sn” for surname, and “displayName” for display name. You do not need to enter a nickname.
- Important! Test out your settings in another browser. If you made a mistake in the settings, you will be locked out of your own account, as the hooks for logging in and logging out will now be tied to the wp_login() and wp_logout() functions. You’ll need database access to fix this if you made a mistake on the settings. This has been fixed in V1.1; see update 12/9/13 below.
That’s all there is to the installation. If you entered all your information correctly, all user authentication will now route through your CAS server and pull user data from your LDAP.
There are two potential pitfalls. One is if your user does not have permission to create a directory for the plugin. That will need to be taken care of on the server side; you will need to give permission to the plugin folder to the WordPress instance. Another is if you used the same browser to check your settings and they were wrong. If you did this, then you will need to deactivate the plugin either by logging in to the server and renaming the plugin folder (which will automatically deactivate the plugin), or by logging in to the database and searching for all “active_plugins” from the wp_options table. Here is a good tutorial on that.
I’ve updated the plug in to allow users who don’t have a CAS account to login. This also means that you can log in as site administrator now, even if there’s a problem with the CAS authentication. You’ll simply need to point your browser to http://yoursiteurl.com/wp-login.php?auth=NOCAS. This will revert the login process back to the WordPress authentication methods. To use this for individual users who do not have a CAS account, you will need to modify your theme’s footer/sidebar to link to the login page using the extra variable. e.g.:
<?php echo “<a href=\””.site_url().”/wp-login.php?auth=NOCAS\”>Log In (No School Account)</a>”; ?>