I think I've already mentioned before that my least favorite chapter from Spring in Action is the one on Acegi Security. That's not because I don't like Acegi, nor is it because I think I did a horrible job in writing it. I think I did an okay job, but wish that I could've done better.
The problem with writing about Acegi is that there is so much to write about. But even for the most basic security configuration, Acegi demands a lot of XML. (I'm sure that you've heard by now that Acegi kills fairies.) With so much required for basic security configuration, it was difficult to describe and I was left with little room for more advanced security configuration. If only the XML was simpler, I could've covered more ground.
Enter Spring Security 2.0. For the past week or so, I've been retrofitting the RoadRantz example from the book to take advantage of the new annotation-driven Spring MVC from Spring 2.5 and to use the new simpler security configuration from Spring Security 2.0. It's been a lot of fun and I've been met with lots of success.
The original Acegi version of RoadRantz' security configuration was well over 300 lines of XML. Sure, some of that may not have been necessary and was only there for illustration's sake. But it was still a lot of XML. But the new security configuration (as of right now) is only 27 lines of XML--less than 10% of the original size. For your amusement, here it is:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd"> <!-- Automatically registers a login form, BASIC authentication, anonymous authentication, logout services, remember-me and servlet-api-integration. --> <http auto-config="true"> <intercept-url pattern="/addRant.htm" access="ROLE_USER" /> <intercept-url pattern="/home.htm" requires-channel="http" /> <intercept-url pattern="/login.htm" requires-channel="https" /> <form-login login-page="/login.htm" /> </http> <authentication-provider user-service-ref="userService" /> <jdbc-user-service id="userService" data-source-ref="dataSource" users-by-username-query="select email,password,true from motorist where email=?" authorities-by-username-query="select m.email,p.privilege from motorist m, motorist_privileges p where m.email=? and m.id=p.motorist_id" /> </beans:beans>
This is still a work in progress and there are some things configured kinda goofy, but it's really starting to take shape. There's only gotcha with the above XML...it doesn't work.
What? Why would I share something with you that doesn't work? Well, it almost works. As of Spring Security 2.0-M2, the <jdbc-user-service>
doesn't officially support customization of the SQL that it uses to lookup user and authorities information. That is, it doesn't support the bolded part of the XML above. That renders it useless for any application that doesn't keep its user information in a table that matches <jdbc-user-service>
's defaults.
But this is open-source, right? Why can't I just fix it myself? That's exactly what I did. First, I opened an issue (SEC-703) to report a possible improvement. Then I checked the Spring Security code out of Subversion, made the necessary adjustments (writing unit-tests along the way), and created a patch to attach to SEC-703.
Now, should the project leadership agree with my changes, some future version of Spring Security (hopefully in time for 2.0 Final) will come with code that I wrote. It feels good to give back. This isn't the first time that I've submitted patches, but it was one of the most fun patches I've submitted because it directly addressed a problem that I encountered just a hours before.