Jan 2
IBM backs CouchDB
icon1 Niklas | icon2 Tags: , , . | icon4 01 2nd, 2008| icon3No Comments »

Damien Katz is going to IBM to work full time on CouchDB. All arranged by Sam Ruby and friends. This is excellent news for the CouchDB community. Besides having Damien being focused on the project, getting IBMs deep knowledge on storage systems, both from DB2 and Domino/Notes I’m sure will be very beneficial.

And on top of all that, the code is moving to Apache and will be relicensed under ASL2. Still no open discussions in Apache Incubator, but I’m guessing that’s where it’s heading. Having CouchDB at Apache will be great! And I like that Apache is getting into more alternative technologies besides the comfort zone of C and Java.

CouchDB is getting more and more interesting to watch by the day.

Update: links was lost in publishing somehow.

Technorati Tags: , ,

Oct 19

Sometimes, when you’re out of luck, you need to use the old Base Java API for WebSphere MQ. That is, not JMS. And you might need to create, or even worse, read a RFH2 header. If this is you, you probably loath the mess that is the RFH2 header structure. It’s a mix of a leading binary structure, followed by zero or more almost-XML structures. I have yet to see a complete specification.

So, what’s a poor hacker to do. I’ve written up a utility class for creating and parsing RFH2 headers as part of the wmq-util library that I’m doing at work. The aim is simple: make it easy to use RFH2 headers without any risk of screwing up. Enjoy and report back bugs and suggestions.

Technorati Tags: , , ,

Jun 11

Starting today, Apache Incubator FtpServer JARs are available from the Apache snapshot repository. This should make it easy to use FtpServer in your Maven 2 build. Just declare the following dependency and you’re done.

    <dependency>
      <groupId>org.apache.ftpserver</groupId>
      <artifactId>ftpserver-core</artifactId>
      <version>1.0-incubator-SNAPSHOT</version>
    </dependency>

Currently, the snapshots will be deployed manually, but I’m working on getting a CI build up and running that would also deploy snapshots automagically.

Jan 13

Sometimes its amazing how slowly development can work. This bug, the lack of scrollbars for the headers panel in Thunderbird, has been open for more than three years. The fix, based on the comments, seems to be a CSS addition of less than 10 lines. The bug has 72 votes and 112 comments which should make it a fairly popular bug. Still, it’s not fixed in Thunderbird 2.0 beta 1.

Luckily, there is a great extension that does fix the problem, and with some hacking of install.rdf it seems to work in 2.0 beta 1 as well.

Jan 6
Email backup
icon1 Niklas | icon2 Tags: , . | icon4 01 6th, 2007| icon31 Comment »

I got some 4 Gb of Outlook .pst files that I use for email backup. A few days ago I got kind of tired of having these in a proprietary format that I could not search together with the rest of my emails. And I planning to switch to Ubuntu which makes things even worse. Also, the GMail-looses-your-mail news going around made me really want to get that GMail backup up and running.

So, I fired up the trusty Thunderbird and set GMail as my POP provider. 10 minutes later, all email in GMail was nicely backed up as mbox. Now, how about those .pst files? I googled, found some tips but none of those that looked attractive and efficient actually worked for me. Having Outlook Express around might have helped, but I don’t any longer. So, the obvious but boring choice of using IMAP to transfer all the emails was made. And, for the last couple of days my poor laptop has been humming away transferring email back and forth to the IMAP server I installed locally. More than half of the data has now been migrated and the result looks really good. Before the weekend is over I should hopefully own my data for good :-)

Jul 16

At work, I’m finishing up an application that uses Acegi Security System for authentication and authorization. Last week, I had to create an example configuration that used Active Directory for verifying users and assigning them roles that would allow them into the application. Now, this is probably pretty easy if you know Acegi and LDAP, but since I’m pretty poor at both of them it took me half a day. To save your time (should you be as ignorant as I am), here’s how I did it.

I should point out that below I use Acegi as the name of Acegi Security System. This is not recommended but I though that it’s a least better then ASS ;-)

To start with, my requirements was that I wanted to use the mail alias (in my case niklas.gustavsson) as the login name, not the CN. In our AD (and most others I presume) this is stored in the mailNickname attribute. If you like to use the sAMAccountName it will work the same way, just replace mailNickname.
Second, I wanted users from three different groups (our three offices) to have access.

The main Acegi file is pretty much the boilerplate config from the “Tutorial Sample” so I won’t go into very much depth on that here. What we need in addition to that files, is a working AuthenticationProvider that can be plugged in. For LDAP, there is LdapAuthenticationProvider. The provider needs two things, an Authenticator and an AuthoritiesPopulator.

The Authenticator

For authenticator there are two options, BindAuthenticator that will try to bind (login) to the LDAP server as the user and PasswordComparisonAuthenticator that will use the LDAP compare function to verify the provided password with that stored in LDAP. I went for BindAuthenticator, can’t really say if this decision makes any difference but it worked for me.

The BindAuthenticator needs the connection details for the LDAP server, provided by a Context, in Acegi a DefaultInitialDirContextFactory. Here you just provide the URL to your server (e.g. ldap://ad.example.com), the DN for the user you want to use for lookups, this needs to be a full DN, and the password for that user. In their example, Acegi includes a BaseDN in the server URL, this did not work for me and my config only started working after removing it.


<bean id="initialDirContextFactory"
class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
<constructor-arg value="ldap://ad.example.com"/>
<property name="managerDn">
<value>CN=queryuser,CN=Users,DC=example,DC=com</value>
</property>
<property name="managerPassword">
<value>secret</value>
</property>
</bean>

Now, here comes the first tricky part. The example in the Acegi documentation uses the userDnPatterns property on BindAuthenticator to perform the bind. Now, I was only able to get this working when logging in using my CN (Niklas Gustavsson) but since I wanted to use the mailNickname I was stuck here. Instead I had to use the filter search capabilities (did I say that Acegi is a marvel of flexibility with the price of complexity?). Here is my understanding of how this works.

  1. Instead of binding directly, Acegi uses the filter to find a matching user
  2. If no user is found, that’s a failure.
  3. If a user is found, takes that users DN and tries to bind using it
  4. Success to bind means that we are okay, failure means incorrect password

So, we need to set up a filter search. This is done using a FilterBasedLdapUserSearch with the following constructor arguments:

  • The BaseDN for the search, for example OU=Users,DC=example,DC=com
  • The filter statement
  • The context factory

I also provided a property to enable search on any sublevel, leaving the following configuration:

<bean id="userSearch" class="org.acegisecurity.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0">
<value>OU=Users,DC=example,DC=com</value>
</constructor-arg>
<constructor-arg index="1">
<value>(mailNickname={0})</value>
</constructor-arg>
<constructor-arg index="2">
<ref local="initialDirContextFactory"/>
</constructor-arg>
<property name="searchSubtree">
<value>true</value>
</property>
</bean>

Now we’re ready to wire up the BindAuthenticator providing the context factory as a constructor argument and the filter search as the userSearch property:

<bean class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
<constructor-arg>
<ref local="initialDirContextFactory"/>
</constructor-arg>
<property name="userSearch" ref="userSearch"/>
</bean>

The AuthoritiesPopulator

Now, with the user authenticated we need to assign it a role that will allow access to the application. The simplest way to do this is with the DefaultLdapAuthoritiesPopulator. This class will populate the user with a set of roles based on the groups of which its a member. By default it will prefix the role name with “ROLE_” and uppercase the group name. So, a user which is a member of “MyAppUsers” and “MyAppAdmins” will get the roles ROLE_MYAPPUSERS and ROLE_MYAPPADMINS. Good enough, but how do we configure the populator? First we need the BaseDN for groups (e.g. CN=GroupsDC=example,DC=com) and second the attribute that you want to use for the role name, in our case “cn”. The configuration would then look like this:

<bean class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
<constructor-arg>
<ref local="initialDirContextFactory"/>
</constructor-arg>
<constructor-arg>
<value>CN=Groups,DC=example,DC=com</value>
</constructor-arg>
<property name="groupRoleAttribute">
<value>cn</value>
</property>
</bean>

What will happen is that Acegi will search this BaseDN for groups of which our user is listed in the “member” attribute. After that, it will take the CN of those groups, prefix, uppercase and assign as roles to the authenticated user.

Now all you need to do is to configure a LdapAuthenticationProvider with the BindAuthenticator as the first constructor argument and the DefaultLdapAuthoritiesPopulator as the last.

The full example configuration can be downloaded here.

The objectDefinitionSource

Last but not least, we need to configure the objectDefinitionSource in the boilerplate file from the tutorial sample to allow users with the correct roles to log in.


<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/login=IS_AUTHENTICATED_ANONYMOUSLY
/**=ROLE_MYAPPUSERS
</value>
</property>

Here we set the role ROLE_MYAPPUSERS should be allowed to access any URL of the application. We make one exception for the login page which any (unauthenticated) user can access, otherwise it would be impossible to log in.

Summary

That’s all you need to talk to an Active Directory and given Acegi’s flexibility you can pretty much bend this configuration any way you want to fit your needs.

I should point out that the possibility to set up all the beans in a simple TestCase instead of having to redeploy and test the web application made trying this out much faster. It also meant that I could try each part (e.g. the FilterBasedLdapUserSearch) in isolation.

Also, the power of Acegi is astounding. Given some (usually quite complex) configuration, it can be tweaked to perform authentication and authorization in pretty much any way imaginable. Very impressive and a great addition to Spring. Hopefully the new configuration support in Spring 2.0 will simplify the XML, I haven’t yet had the possibility to play with it.

Ah, glad to get that of my chest. Feedback, improvements are of course welcome!

Apr 12
Open source donation
icon1 Niklas | icon2 Tags: , . | icon4 04 12th, 2006| icon31 Comment »

As noted by Mårten, at work we have decided to give some back to the open source community. We’re quite heavy users of open source software, both for our internal systems (e.g. Ubuntu, Subversion, Apache, Tomcat, Maven) and our software (e.g. Spring, Hibernate, commons). As a way of showing our gratitude we will be donating money to projects voted by our employees a couple of times per year.

Of course, as hopefully nice citizens we also try to contribute back improvements made on software we use, but that goes without saying :-)