I’ve now upgraded my instance of WordPress to 1.5. Very easy too, if you follow the instructions at:
Install/Upgrade to 1.5
How to copy your database
I’ve now upgraded my instance of WordPress to 1.5. Very easy too, if you follow the instructions at:
Install/Upgrade to 1.5
How to copy your database
Following on from adding LDAP to WordPress 1.2.1, I’ve ported it to 1.5.
The basic mechanism is the same, i.e. after successful authentication, the cookie is modified to store a hash of the username and the LDAP marker, instead of the password. LDAP accounts are quite often used institution-wide for single sign on (SSO), so I think it’s a bad idea to store that password anywhere outside the LDAP server, even if it’s double hashed. On Novell NDS you can’t even get the password, you can only compare it.
The modified files for 1.5 are:
As before, you can enable LDAP authentication in wp-config.php:
setting “LDAP_ENABLED” to “true” will turn on LDAP authentication. Setting it to “false” will turn it off and WordPress will revert to normal database authentication and cookie setting.
A change from 1.2.1 LDAP is the “admin” user is not authenticated via LDAP. So, if your LDAP server goes down, you can still get in to your blog.
One thing to note, is if you turn on LDAP authentication, all users of your instance of WordPress must have local accounts as before but they also must have LDAP accounts or they won’t get in.
To address security concerns, I’ve trimmed the distributed files and changed all .h files to .php. I’ve also bundled a .htaccess in the /ldap directory to deny all access.
You can follow a discussion on LDAP authentication here
The link below includes all the modifications to improve security.
Download the LDAP modifications for WordPress 1.5
JDK 1.4.2_05 gave us a headache with Tomcat and xmlsec. It seems it ships with a buggy xalan.jar:
public static FuncLoader m_functions;
private static FuncLoader m_functions;
so you get the error:
java.lang.IllegalAccessError: tried to access field org.apache.xpath.compiler.FunctionTable.m_functions from class org.apache.xml.security.Init
To solve this problem, download the latest xalan.jar and copy it to:
This will make sure Tomcat loads the proper version of xalan instead of the buggy JDK one
Well, learning Struts on the G4 and all was well. I’d got up to basic validation and database querying with DataSource but when I put it on the G5 it blew up with the error:
/usr/local/tomcat/work/Catalina/test.ac.uk/struts/org/apache/jsp/index_jsp.java:154: _jspx_meth_bean_message_3(javax.servlet.jsp.tagext.JspTag,javax.servlet.jsp.PageContext) in org.apache.jsp.index_jsp cannot be applied to (org.apache.struts.taglib.html.LinkTag,javax.servlet.jsp.PageContext)
if (_jspx_meth_bean_message_3(_jspx_th_html_link_0, _jspx_page_context))
Nesting a bean tag inside an html tag was causing the problem on Tomcat 5.0.19 on Mac OS X:
<%@ page contentType=”text/html;charset=UTF-8″ language=”java” %>
<%@ taglib uri=”http://struts.apache.org/tags-html” prefix=”html” %>
<%@ taglib uri=”http://struts.apache.org/tags-bean” prefix=”bean” %>
<head><title><bean:message key=”index.title” /></title></head>
<html:link forward=”auth”><bean:message key=”index.link.auth” /></html:link>
The bean:message nested inside the html:link was causing the compilation error. I just couldn’t get it work on the G5.
In the end, I upgraded to Tomcat 5.0.28 and it fixed the problem!
OK, it’s time to update my ageing Tomcat. I was running 5.0.19 on Mac OS X but for some reason was getting strange Struts errors, such as not being able to embed bean:message tags inside html:link tags. It works fine on the G4 but not the G5.
First stop then is Tomcat central but what’s the story with the connector? Apparently mod_jk2 is dead, due to lack of developer interest!
mod_jk2 is dead, long live mod_jk (again)
So what’s the latest mod_jk? That’s an easy question with no easy answer. The releases so far have gone:
mod_jk 1.2.7 beta -> beta2 -> beta3 -> 1.2.8 rc1
what happened to the release of 1.2.7? and why would I want an rc? What is an rc? If it’s a candidate for release then it’s obviously not a proper release, so where is the proper release?
According to this page it’s mod_jk 1.2.6. OK, download that but what trickery is this? It expands to mod_jk 1.2.8! There is no 1.2.6 or 1.2.7!
Anyway, once the Tomcat versioning and docs hurdles are overcome it’s a simple case of following the instructions on the installation page. In short, for Mac OS X:
You’ll then have mod_jk.so in /usr/local/apache/modules
Before you can use Tomcat 5.5.7 on OS X, you’ll have to go back to the Tomcat download page and get the compatibility package. It’s not obvious. I finally found it as “5.5.7 Compat tar.gz”. Expand it to get the files:
and copy them to the corresponding directories in your Tomcat 5.5.7 directory.
Next we have to configure /usr/local/apache/conf/workers.properties, using this page.
The two most important settings are:
Next we have to define a worker to handle requests transferred from Apache. I just deleted the default AJP12 and AJP13 workers as Tomcat seems to ignore everything after the first worker:
This sets up a worker called “sgarbh” which you can use in your Apache virtual hosts to hook servlet requests. In fact, that’s what we’ll do now. Set up Apache to work with Tomcat.
add these lines at the end of the file:
LoadModule jk_module modules/mod_jk.so
Here’s what they mean:
So now we’ve defined a worker to handle servlet requests, loaded the connector into apache. What’s still required? We need to map virtual hosts or content areas within virtual hosts to tomcat workers:
CustomLog /var/log/apache/logs/test.uni.ac.uk-access_log combined
DirectoryIndex index.htm index.php
JkMount /test-servlet/* sgarbh
The JkMount directive tells Apache to send all requests for http://test.uni.ac.uk/test-servlet to the tomcat connector called “sgarbh”, which we defined earlier in our /usr/local/tomcat/conf/workers.properties.
Next we have to fool around with aliases and paths. This is where you wished mod_jk2 hadn’t disappeared as mod_jk is not as easy to configure. To divert all requests to /struts to Tomcat, you’ll have to add this lot to you VirtualHost container:
Alias /struts “/WWW/struts”
Options Indexes +FollowSymLinks
JkMount /struts/* sgarbh
deny from all
UHI user visits the eggheads at SMO, who have a wireless network. The user, after a long day having his brain cooked by the SMO boffins decides he wants to check his email using the Groupwise web client, as he doesn’t have the mail client on his laptop. So, he powers up the machine and connects to the SMO wireless network.
Here’s the logical flow:
Now, the wireless network is serviced by a firewall running on a Linux machine. Upon initial connection, the laptop is assigned a DHCP address and all traffic from that laptop is NATted to port 80 on the firewall.
The only thing on port 80 is a web service, whose only function is to take the REMOTE_HOST of the connection, find out it’s MAC address, enable it in the iptables rules on the firewall and remove the NAT. Thus allowing traffic from that MAC address to flow freely.
The web services is protected by a standard Shibboleth target, which, when it detects access to the web service intitiates a shibboleth session and the user is redirected to the UHI institutional authentication page.
After successfully authenticated, the user is redirected by Shibboleth back to the web service on the firewall which uses their REMOTE_HOST to get their MAC address and let them through the firewall. The NAT is also removed so they can roam freely on the network.
The firewall can set a TTL on the entry based on attribute TTLs coming back from the attribute store when they authenticate
Taking a break from documenting the SP side of Shibboleth and looking at pictures of my erstwhile colleagues munching cakes at the last Bodington developers’ meeting at Leeds uni, it struck me that people might think I’m strange, always on the lookout for cake trolleys at whatever meeting I happen to enlighten
Although it doesn’t seem in the slightest out of the ordinary to me, my non technical aquaintances do rib me now and then over my cakeophilia! We’ll, here’s the reason.
Here at the Guanxi engine room, we use eXtreme Programming quite a lot, if not exclusively. It’s the real way to develop software. None of this outdated waterfall nonsense, requirements specification and fighting to get bug ridden code out of the door by the deadline. No siree, we indulge in customer interaction, iterative development processes and the odd bit of pair programming, though I do find that a bit stressful as it means someone else is in the room with me, next to the cake trolley, the only one
XP rewards good developers with a real stake in the application planning, contributing to schedules and offering meaningful and respected opinions on functionality versus business risk.
To do this, however, we must employ the most resource intensive organ we have – the brain, which as we all know, consumes resources at an awesome rate and if not kept in tip top condition and well fed, would pop out and go find another XPer who could feed it.
Don’t take my word for it. The following extracts are from “Extreme Programming Explained” by Kent Beck. Yes, the man himself.
On the job of the XP coach, the motivator:
“But perhaps the most important job for the coach is the acquisition of toys and food…”
“Food, also, is a hallmark of XP projects. There is something powerful about breaking bread with someone. You have an entirely different discussion with them when you’re chewing…”
“…so XP projects always have food lying around…” (though not for long at Guanxi central!)
On the rare case where tests fail:
“…if we’re back at 100%…we can have tea and a snack…”
and what better snack than a trolley laden with scrumptious cakes?
So, the next time I turn up at a meeting, ready to enlighten all around, don’t scoff at my request for a cake trolley. It means I’m back at 100%
Just leave the scoffing to me!
The <Applications> element in shibboleth.xml is the wrapper for all the applications that this SP provides. There is only one <Applications> element and it provides default session handling metrics, which individual applications on the SP can choose to override. Let’s take a look at the default session handling for our SP:
<Sessions lifetime=”7200″ timeout=”3600″ checkAddress=”true” wayfURL=”https://shorigin.uhi.ac.uk/SSO” shireURL=”/Shibboleth.shire” shireSSL=”false”/>
Here’s what the Sessions attributes mean:
This is where you override the default “flying pig” error pages of shibboleth. Just design some nice marketing friendly pages and record their URLs here.
<CredentialUse TLS=”uhi” Signing=”uhi”>
<RelyingParty Name=”leeds” TLS=”leedscreds” Signing=”leedscreds”/>
and it’s associated:
CredentialUse is used to tell shibboleth how to sign and send attribute requests to IdP components, such as an AA. Here’s what the attributes mean:
Our example shows a default TLS and signing policy, both specified by “uhi”. This means that our SP will use the specified keys and certs when signing attribute requests for any IdP. If you need to sign attribute requests differently for a certain IdP you’re talking to, you can override the default by using the RelyingParty element. We’ve done this for signing requests to the University of Leeds’ IdP.
<saml:AttributeDesignator AttributeName=”urn:mace:dir:attribute-def:eduPersonTargetedID” AttributeNamespace=”urn:mace:shibboleth:1.0:attributeNamespace:uri”/>
<saml:AttributeDesignator AttributeName=”urn:uhi:ac:uk:attribute-def:givenName” AttributeNamespace=”urn:mace:shibboleth:1.0:attributeNamespace:uri”/>
It’s here that we specify what attributes we want back from AA. As you can see, we’re saying we want any AA that replies to us, to send us the user’s eduPersonTargetedID attribute and also the Novell NDS givenName attribute. As we said when configuring AAP.xml, it’s recommended that we always use urn:mace:shibboleth:1.0:attributeNamespace:uri for the namespace for any attributes. You have to be aware though, that these attribute requests are subject to IdP attribute release policies, i.e. if the user chooses not to release their givenName to our SP then their AA won’t send it back and they won’t get in. Well, it’s up to the application to decide, not shibboleth, which just arranges for the attributes to be fetched and presented to the application. If givenName isn’t in the application’s environment for some reason such as not being specified in AAP.xml and therefore being physically removed from the assertion or due to the user choosing not to release it, then the application must make a decision on whether to grant access to that user. If .htaccess is used, then user won’t get in. More sophisticted authorisation rules in the application could provide limited access.
<AAPProvider type=”edu.internet2.middleware.shibboleth.target.provider.XMLAAP” uri=”/usr/local/shibboleth/etc/shibboleth/AAP.xml”/>
This is the attribute acceptance policy for our SP. I’ve already documented this here. You can either choose to have a separate file, such as AAP.xml, or you can copy your AttributeRules directly into shibboleth.xml. I prefer to use AAP.xml
<FederationProvider type=”edu.internet2.middleware.shibboleth.common.provider.XMLMetadata” uri=”/usr/local/shibboleth/etc/shibboleth/IQ-sites.xml”/>
Similarly, as we did with AAP.xml, you can either include providers from IQ-sites.xml, or copy them directly to shibboleth.xml. As I prefer the modularised approach, we’ll look at IQ-sites.xml here.
<TrustProvider type=”edu.internet2.middleware.shibboleth.common.provider.XMLTrust” uri=”/usr/local/shibboleth/etc/shibboleth/IQ-trust.xml”/>
Again, we’ll keep these setting separate and document IQ-trust.xml here.
<RevocationProvider type=”edu.internet2.middleware.shibboleth.common.provider.XMLRevocation” uri=”/usr/local/shibboleth/etc/shibboleth/IQ-trust.xml”/>
This allows our SP to control IdP SSL communications by referring to a list of revoked certificates. We’ll document this in IQ-sites.xml
You only need this if you’re talking to ancient versions of shibboleth origins. We won’t be, so we won’t need this element in shibboleth.xml
<Sessions lifetime=”7200″ timeout=”3600″ checkAddress=”true” shireURL=”/secure/admin/Shibboleth.shire” shireSSL=”true” cookieProps=”; path=/secure/admin; secure” wayfURL=”https://wayf.internet2.edu/InQueue/WAYF”/>
<saml:AttributeDesignator AttributeName=”urn:mace:dir:attribute-def:eduPersonPrincipalName” AttributeNamespace=”urn:mace:shibboleth:1.0:attributeNamespace:uri”/>
If you want to override the default Applications behaviour, which applies to all applications that our SP acts as an attribute gateway for, you can specify what you want in an Application element.
The “id” attribute of the Application element refers to the entry in applications.xml that defines an application, such as another virtual host. When our SP is routing attributes to this new virtual host, it will use specific lifetime, timeout, wayfURL etc. instead of the defaults. It will also only ask for the eduPersonPrincipalName attribute instead of eduPersonTargetedID and givenName which all the other applications ask for.
So how do you specify an applications.xml?
<RequestMapProvider type=”edu.internet2.middleware.shibboleth.target.provider.XMLRequestMap” uri=”/usr/local/shibboleth/etc/shibboleth/applications.xml”/>
The RequestMapProvider element sits in the SHIRE element and tells our SP where our applications mapping file is located. It’s in here that we’ll specify a pernickety application that wants an environment that the others don’t
This file is your Attribute Acceptance Policy engine. It’s here that you tell shibboleth what to do with incoming attributes from an AA. The eduPerson attributes are already set up for you, so we’ll look at the one I use to map the Novell NDS attribute groupMembership to specific acceptance criteria and also how to let scripting languages get at the attribute.
Here’s the SAML coming from the AA. I’ve left out the namespace declarations and wrapping SOAP and SAML elements for clarity:
<NameIdentifier Format=”urn:mace:shibboleth:1.0:nameIdentifier” NameQualifier=”idp.org.ac.uk”<5387459</NameIdentifier>
<Attribute AttributeName=”urn:org:uk:attribute-def:groupMembership” AttributeNamespace=”urn:mace:shibboleth:1.0:attributeNamespace:uri”>
The above Attribute/AttributeValue pairs show that the user identified as “5387459″ is a member of the “admins” and “testers” groups at their organisation.
It’s recommended that you use “urn:mace:shibboleth:1.0:attributeNamespace:uri” for the “AttributeNamespace” of your attributes and choose an appropriate URN for the attribute itself. As you can see, our attribute is scoped to “urn:org:uk”.
So, shibb has redirected to the IdP, the user has been authenticated and the attributes have arrived at the SP. What next? How do you actually use the attributes? The steps are quite simple:
Here we’ll specify how the group membership is propagated from shibboleth to apache. To do this, we first need an entry for the attribute. This will stop the SP filtering out the attribute and removing it from the assertion:
<AttributeRule Name=”urn:uhi:ac:uk:attribute-def:givenName” Header=”Organisation-First-Name” Alias=”firstname”>
The above AttributeRule states the following:
Puingean cudthromach bho Eilean an Fhraoich