FWIW, the problem was that I hadn't provided credentials for an acegisecurity identity in my applicationContext.xml so it was trying to use anonymous access to search for user roles.
Code:
<bean id="initialDirContextFactory"
class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
<constructor-arg value="ldap://localhost:389/dc=base,dc=co,dc=nz"/>
<!--
For bind authentication don't require managerDn, but it is used for
picking roles without requiring anon access.
-->
<property name="managerDn">
<value>cn=acegisecurity,ou=people,dc=base,dc=co,dc=nz</value>
</property>
<property name="managerPassword">
<value>**************</value>
</property>
</bean>