While working on a new WordPress-based website for Drexel Smart House (DSH) today, I wanted to provide an easy single-sign-on (SSO) solution for DSH members. DSH already uses Google Apps for everything, so why not use their Google Apps emails to login to WordPress as well? Should be easy, right?
I found a couple of ways to do this… the first, and seemingly easiest, is by using the RPX plugin from Jan Rain. However, I didn’t want to even offer the option to users of choosing among Facebook, Twitter, Google, MySpace, Yahoo, OpenID, and more to login. I wanted a simple, familiar username/password box that only accepted @drexelsmarthouse.com accounts and verified the password with Google Apps.
The second way, and the one DSH is using, is a creatively named plugin called 3rd-Party-Authentication. It allows the administrator to configure any POP3 or IMAP based email to be used for authentication; as a bonus, it has Google Apps, Gmail, and GoogleMail accounts pre-configured. So if all you want is Google Apps authentication, just enter your domain name. Easy!
Plus, its pretty configurable; the admin can easily select the Google Apps domains and custom email (POP3/IMAP) domains to be allowed, as well as specifying whether Gmail and GoogleMail are allowed. It even offers to auto-create new users from the allowed domains for you!
Plus, the interface is exactly what I wanted, i.e., nothing out of the ordinary.
It even has built-in user instructions. Perfect!
The problems come when trying to get it to work. This little beauty has almost zero documentation or tutorials online. This is where I come in
Like most of you reading this tutorial, I expect, I was getting very frustrated when it didn’t appear to be working. After reading the sparse comments scattered about the web, I had my first a-ha! moment.
Secret #1: your username has to be your Google Apps (or IMAP/POP3) email.
The plugin doesn’t match logins to WordPress users based upon their email field, as you (and I) probably expect(ed). So, after installing the WPVN Username Changer plugin, I changed my username to my @drexelsmarthouse.com email address. After changing the password stored in WordPress to a random string (to avoid a false success if both passwords happened to be the same), I tried to login again. Success!
Next, I didn’t want to add WordPress user creation to my IT workflow, so I enabled auto-creation of users. I tried it out on one of our Google Apps test accounts, and it worked! But not so fast… I had one of my friends in DSH test it out to see if it worked for him… and of course it didn’t. Instead, it displayed the uber-informative error message “Invalid username”.
<mumbles>stupid plugin made me look like a fool.</mumbles>
So I set about trying to figure out the issue; thankfully, my friend let me change his Google Apps password so I could debug the issue on his account, repeatedly simulating (i.e., causing exactly) the failure while stepping through the code one line at a time and watching the wp_users table in the database. (I originally suspected an issue with the dot in his username/email for some reason.)
Eventually, I found out the error message was completely wrong. What was actually happening had nothing to do with the username, but rather the user’s email address. The user was not being added; the wp_create_user function was returning the error ‘This email address is already registered.” But he wasn’t registered in the wp_users table. So… How?
Secret #2: The plugin was auto-creating users with an empty email address (empty-string: ”).
The first auto-created user succeeded, creating the user without an email address (as the secret says). The second auto-created user also tried to use an empty email, but it was already taken by the first user. Emails aren’t being correctly set/stored. There’s the problem.
I’ve already alerted the plugin author of this issue, and hopefully it will be patched in the next minor release. In the meantime, you can just change one line in the code yourself to make it work. Open up the Plugins > Editor SubPanel to the file 3rd-party-authentication/3rd-party-authentication.php.
Inside the login_failed() method, update the call to wp_create_user from
$user_id = wp_create_user( $username, $random_password, '');
$user_id = wp_create_user( $username, $random_password, $username );
There is a repercussion for people who care, though. Namely, this is terrible in terms of database normalization; changing your email address does not change your username, and thus you could end up signing in with a different email address than that used by WordPress (and displayed on your author profile). This could be confusing to users…
UPDATE: If you get tired of seeing the “ERROR: The username field is empty” on the initial load of your login page, there is an easy fix. In the same file (3rd-party-authentication/3rd-party-authentication.php), simply replace
if ( '' == $username ) return new WP_Error('empty_username', __('<strong>ERROR</strong>: The username field is empty.')); if ( '' == $password ) return new WP_Error('empty_password', __('<strong>ERROR</strong>: The password field is empty.'));
with the following:
if ( '' == $username || '' == $password) return new WP_Error();