Shibboleth Wordpress plugin
The WordPress content-management system can replace or augment its built-in authentication mechanism using the WordPress Shibboleth plug-in.
(The following description is adapted from Markus Kuhn's 2010-03-22 posting to cs-raven-discuss@lists.cam.ac.uk.)
The Shibboleth plugin has the following nice properties:
- It will autogenerate a new account for a user who has never logged in before.
- It will prefill the user profile form fields with values that the WordPress admin can select from Shibboleth attributes (= Lookup data), and you can also select which of these fields the WordPress user can override.
- It allows the traditional WordPress login to coexist with a Shibboleth-based login (i.e., there is just a little Shibboleth link appearing on wp-login.php), or you can make the Shibboleth login the default.
- It allows you to assign default user roles based on Shibboleth attributes.
Under WordPress, you just have to make sure that your local users are using CRSid as their WordPress login name, and you have to migrate them otherwise before they can use it. (Not a big deal for a small user base: In WordPress you cannot rename a user, but they can create a new account and when you delete old accounts of users, WordPress will offer you to reattribute all their past posts to another account.)
Installation
Just follow one of the the usual procedures for installing WordPress plugins. A particularly convenient way of doing this is via a Subversion checkout:
cd wp-content/plugins/ svn co http://plugins.svn.wordpress.org/shibboleth/tags/1.4 shibboleth
This way, you won't forget where you got it from and can easily upgrade in future using "svn switch". (If you are unfamilar with this way of installing WordPress and its plugins, see also http://codex.wordpress.org/Installing/Updating_WordPress_with_Subversion)
More details
When I added the Shibboleth pluging 1.4 to our WordPress 3.1 site http://www.wolfson.cam.ac.uk/news/, I configured it under Settings|Shibboleth in the WordPress dashboard as follows:
Session Initiator URL: https://www.wolfson.cam.ac.uk/Shibboleth.sso/Login Logout URL: https://www.wolfson.cam.ac.uk/Shibboleth.sso/Logout Password Change URL: https://raven.cam.ac.uk/auth/account/ Password Reset URL: Shibboleth is default login: ticked User Profile data mapping to Shibboleth attributes: Username: uid First name: givenName (not managed) Last name: sn (managed) Nickname: eppn (not managed) Display name: displayName (not managed) Email Address: mail (managed) User role mappings: Role Mappings: [I emptied all the fields] Default role: Subscriber Update User Roles: not ticked
I configured Shibboleth as the default login, as the non-Shibboleth login no longer works (due to my more paranoid <Path> configuration, see next section) and would just result in an Apache/Shibboleth access-denied error message. I decided not to use the User role mapping facilities of the plugin (mostly because I still find Lookup to be a bit wanting as a central group-membership management service, i.e. ugly numeric unique group identifiers, lack of scriptable access for automatic updating of group lists by nightly cron scripts).
The existence of the Shibboleth WordPress plugin was the reason why I installed Shibboleth on our webserver, and it works very well.
The installation of the Shibboleth SP was also a very smooth process, especially thanks to the official RPMs available from the openSUSE Build Service and the good documentation on Shibboleth_documentation_and_HOWTOs.
I got an SSL certificate for our site to enable HTTPS and I've added to the <Session> element the attribute handlerSSL="true", as described in SSL, certificates and security with Shibboleth. That eliminated a security warning that Firefox users otherwise would get before the after-Raven redirect. However, I have not added the cookieProps="; path=/; secure" attribute recommended there, as this caused Shibboleth to break for HTTP (i.e., non-HTTPS) users, see Shibboleth FAQs#Looping_between_SP_and_IdP_after_setting_cookieProps. This way, people now can use Raven/Shibboleth both via HTTP or HTTPS, as they wish; I didn't want to force them to always use HTTPS using redirectToSSL="443".
Using Shibboleth to harden WordPress security
WordPress (like many complex PHP applications) has a less than ideal record regarding its security. See this BBC report on how wide-spread WordPress break-ins by spammers have been in UK academic web sites.
If you distrust the security of WordPress, you can use Shibboleth to provide not just a login service but also an additional layer of protection. Configure Shibboleth to require a session before the user is allowed to execute anything in the wp-admin/ folder. This substantially reduces the parts of WordPress potentially exposted to attacks, because it requires that any type of attack that requires either a login or the ability to access a file in wp-admin/ will only be possible after first logging/breaking into Raven. However, this also disables support for the traditional WordPress password login option (i.e., only Raven users will be able to login).
The plugin documentation tells you to configure Shibboleth with requireSession="false" for all WordPress-related files. Here, we deviate from that practice somewhat:
Four our WordPress site http://www.wolfson.cam.ac.uk/news/, I merged into my shibboleth2.xml file the following three <Path> rules:
<RequestMapper type="Native"> <RequestMap applicationId="default"> <Host name="www.wolfson.cam.ac.uk"> <Path name="news" authType="shibboleth" requireSession="false"> <Path name="wp-admin" authType="shibboleth" requireSession="true"> <Path name="async-upload.php" authType="shibboleth" requireSession="false"/> </Path> </Path> </Host> </RequestMap> </RequestMapper>
This makes sure that Shibboleth requires a session for any access to the wp-admin/ directory, with the exception of wp-admin/async-upload.php, which is a callback used by a Flash file-upload application. WordPress does not (yet) forward the necessary cookies for this Flash application to participate in a Shibboleth session, therefore this callback has to be excluded at the moment.