Thursday, 30 August 2007

How to implement remember me using acegi

I have extended the example application showing how to do form based login using acegi.

You need to apply the following changes to the securityContext.xml:

securityContext.xml (download)

Remember me beans:

<!-- remember me processing filter -->
<bean id="rememberMeProcessingFilter"
class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="rememberMeServices" ref="rememberMeServices" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="rememberMeServices"
class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService"> <ref local="memoryAuthenticationDao"/>
</property>
<property name="key" value="someTokenName"/>
</bean>

<bean id="rememberMeAuthenticationProvider"
class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="someTokenName"/>
</bean>
Apply the following changes to existing beans:
Add the rememberMeServices to the logoutfilter for the logout filter to invalidate the remember me cookie.
<bean id="logoutFilter"
class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg index="0" value="/index.jsp"/>
<constructor-arg index="1">
<list>
<ref local="securityContextLogoutHandler"/>
<ref local="rememberMeServices"/>
</list>
</constructor-arg>
</bean>

Add the rememberMeProcessingFilter to the filterchain for the remember me checks to be performed when a user hits a acegi protected URI:
<bean id="filterChainProxy"
class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,rememberMeProcessingFilter,authenticationProcessingFilter,logoutFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>

Also remember to set the rememberMeServices at the authenticationProcessingFilter to overwrite the default NullRememberMeServices with your rememberMeServices. That will provide acegi with a service to handle remember me token validation (took me a bit of debugging to find this error)
<bean id="authenticationProcessingFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/index.jsp?login_error=1"/>
<property name="defaultTargetUrl" value="/secure/securecontent.jsp"/>
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>


Finally extend your login form with a checkbox to let your end user be remembered. The default parameter name is _acegi_security_remember_me:
<tr>
<td>Remember me:</td>
<td><input type="checkbox" name="_acegi_security_remember_me"/></td>
</tr>
Sample (download)
I also provided a simple webapp demonstrating the implementation, just:
  1. download
  2. unzip
  3. type $mvn jetty:run
  4. go to: http://localhost:8080/basicAcegiExample
  5. type user, password as credentials

Monday, 27 August 2007

How to implement formbased authentication with acegi - no container dependencies

I couple of days ago I implemented a sample application illustration the minimal configuration needed for doing basic authentication using acegi. I have decided to take the next step and show a sample of a form based authentication solution - still without any container dependencies. Having no dependencies to a specific container seems to gain a bit of momentum in the Java community these days and Per wrote a interesting blog about keeping your deployment thin and lightweight.

Based on my last basic authentication example you only need to change the following:

See securityContext.xml (download)

ProcessingFilter
Switch the basicProcessingFilter with this one:

<!-- Processes formbased authentication.
The html form should contain to input fields: j_username and j_password.
The post of the form should point at the value of the "filterProcessesUrl"
in this case /j_acegi_security_check -->

<bean id="authenticationProcessingFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/index.jsp?login_error=1"/>
<property name="defaultTargetUrl" value="/secure/securecontent.jsp"/>
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
</bean>

Also remember to change the use in your filterChainProxy.
...
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
...
AuthenticationEntryPoint
Switch authenticationEntryPoint with this:
<!-- changed to work with formbased login -->
<bean id="authenticationEntryPoint"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/index.jsp"/>
</bean>
Further I changed the UserDetailsService as my own implementation could be swapped with an org.acegisecurity.userdetails.memory.InMemoryDaoImpl and still be a lightweight in memory userdetails implementation for the sake of the example:
<!-- implemented memory dao -->
<bean id="memoryAuthenticationDao"
class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
<property name="userMap">
<value>user=password,USER</value>
</property>
</bean>
Logout
Contrary to basic authentication you are able to let the user logout without closing the browser.

Add the following logoutFilter to the filterChainProxy
...
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,logoutFilter,exceptionTranslationFilter,filterInvocationInterceptor
...
and create a logout handler like the SecurityContextLogoutFilter:
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg index="0" value="/index.jsp"/>
<constructor-arg index="1">
<list>
<ref local="securityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>

<bean id="securityContextLogoutHandler"
class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
This snippet will handle a logout when the user requests the /j_acegi_logout that is the default url. Can be changed as a parameter to the logout filter.

Actually I found this api documentation for the BasicProcessingFilterEntryPoint indicating that it is possible to logout using basic authentication without killing the browser:
/**
* Used by the <code>SecurityEnforcementFilter</code> to commence authentication via the {@link
* BasicProcessingFilter}.<P>Once a user agent is authenticated using BASIC authentication, logout requires that
* the browser be closed or an unauthorized (401) header be sent. The simplest way of achieving the latter is to call
* the {@link #commence(ServletRequest, ServletResponse, AuthenticationException)} method below. This will indicate to
* the browser its credentials are no longer authorized, causing it to prompt the user to login again.</p>
*
* @author Ben Alex
* @version $Id: BasicProcessingFilterEntryPoint.java 1877 2007-05-25 05:33:06Z benalex $
*/
I tried the suggested commence solution in my basic autentication example, but did not have success. If you are able to implement the commence solution let me know.

Sample (download)
I also provided a simple webapp demonstrating the implementation, just:
  1. download
  2. unzip
  3. type $mvn jetty:run
  4. go to: http://localhost:8080/formbasedAcegiExample
  5. type user, password as credentials
Next step
Using formbased login you can easy implement "remember me" functionality. In a couple of days I will have a sample for that as well. I will update this post with a link when the time comes. I have implemented a remember me example and it is available here.

Further documentation

Wednesday, 22 August 2007

Does a universal icon set exist?


Recently I attended a Productive Human Interfaces course held by Jim Coplien.
Productive human interfaces isn't about what graphical elements to use and how to align those, but much more about the human understanding of applications based on psychology. A really interesting course by the way.

Even though the course wasn't all about graphical elements we talked about how icons can be used in designing productive user interfaces and the difficulty of finding the right icons to use - as the icons often has to fit both the context and locale they are being used in.

In that occasion my colleague Bo, told a quite funny story about how some sort of "icon council" once tried to agree upon some universal icon set. They where ment to be used in airports, so they had to be interpreted by all nationalities. After a long time they could agree upon arrows as being universal. No body could misunderstand the symbolic of an arrow pointing in a direction, right?
But actually in some areas of Africa an arrow is a symbol of a birds footprint walking in the opposit direction, hence pointing the different way :-)
Unfortunately I can't find any material proving the story, but it verymuch illustrates the difficulties of chosing icons.

Furthermore I stumble upon this blog where people eagerly discusses icons and usability.

Tuesday, 21 August 2007

The preferred multidimensional html/css menu

Yesterday I wrote about how friends and family from time to time asks for help when developing some homegrown php project and today was no exception.
I was asked if I could recommend a simple but efficient multi dimensional menu that could fit into a left column of a website.

A couple of years back I remember that I used some menu relying on a homegrown javascript library doing the best to take care of the many different browsers javascript implementation.
The actual menu content was placed inside lots of tables hence it wasn't easy to maintain.

Today many different opensource dropdown menu's are available so the job is more to look up the one that suites you best, than writing a bunch of code and markup - and the one I ended up with is the extended suckerfish dropdown menu.
It is almost a html/css only menu (of course some javascript is nessesary to please IE!) and was very simple to implement.
The menu content is rendered as unordered list items - (ul and li elements) so serverside generation of the menu is easy.

Customize it
The default implementation represents the menu as a normal top menu, so a bit of customization had to be done to make the menu fit as a left site menu.

The following did the trick:

/* set the width of the entire menu */
#nav {
width: 10em;
}


/* remove this as it aligns the toplevel menu to the left of eachother
#nav li {
float: left;
width: 10em;
}
*/

/* add this as it let the first level menu appear to the left of the first level menu */
#nav li ul {
margin: -1em 0 0 10em;
}

#nav li ul ul {
margin: -1em 0 0 10em;
}

I must say the menu is very cool and I can indeed recommend it!

Drawback
The only drawback of being a pure html/css implemention is the lack of ability to delay the time it takes to hide submenus.
It will happen instantly as the cursor removes focus from the menu and you will quite often find yourself "loosing" the menu as you tries to navigate down the menu tree.

Friday, 17 August 2007

The preferred operating system for rapid development setup

From time to time I am asked to help some friend or family writing php code. That is the drawback of being in the software business (luckily they don't ask me to fix their car).
I am not a php developer by nature, but of course I am willing to help.

I recently switched to mac and haven't had the change to install a usefull apache (the one that mac os x is shipped with isn't capable of running php 5), neither did I have php on my machine.

Instead of setting it all up by hand I found MAMP. It is bundled with php4, php5, mysql and apache - all wrapped up in one simple application easy to install and just as easy to uninstall.

I haven't had the chance to dig that much into Rails yet, but my colleague showed me the Locomotive application that seems to have the same benefits as MAMP.

I simply love how easy it is to setup a development environment on my mac.

Tuesday, 14 August 2007

How to implement basic authentication with acegi - no container dependency

I have always implemented basic authentication by depending on a specific container implementation - always with the drawback of not being able to easy switch between containers in development, test and production.
Now I stood in front of another implementation and decided to look into Acegi's possibilities. If Acegi could provide a basic authentication mechanism bundled in my application I could get rid of the container dependency.
I did use Acegi on one other project to do form based login, but at that time the API changed between each little minor release making it a pain to upgrade.
Now they promise to keep the API stable so I thought it was about time give it a new fair chance to improve the first impression I got.

And I must say it did!

Following is a simple securityContext.xml needed to perform basic authentication using spring and acegi.
I provided a very simple UserDetailsService for the sake of the example. You should probably be using the
org.acegisecurity.userdetails.jdbc.JdbcDaoImpl implementation instead - or any other implementation that suites your setup.

securityContext.xml (download)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

<!-- ======================== FILTER CHAIN ======================= -->

<bean id="filterChainProxy"
class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,basicProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>

<!-- responsible for setting up a security context holder for other
authentication mechanisms to work with -->
<bean id="httpSessionContextIntegrationFilter"
class="org.acegisecurity.context.HttpSessionContextIntegrationFilter">
<!-- no session should ever be created. We are processing basic
authentication credentials on each request -->
<property name="allowSessionCreation" value="false"/>
</bean>

<!-- Processes basic authentication headers and works together with the
provided authentication manager and
entry point to perform basic authentication -->
<bean id="basicProcessingFilter"
class="org.acegisecurity.ui.basicauth.BasicProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationEntryPoint"
ref="authenticationEntryPoint"/>
</bean>

<!-- filter responsible for access decisions. What urlrequests may be
processed by which roles -->
<bean id="filterInvocationInterceptor"
class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager">
<ref local="httpRequestAccessDecisionManager"/>
</property>
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=USER
</value>
</property>
</bean>

<!-- filter responsible for translating exceptions and delegating to the
provided authenticationEntryPoint -->
<bean id="exceptionTranslationFilter"
class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint"
ref="authenticationEntryPoint"/>
</bean>

<!-- ======================== AUTHENTICATION ======================= -->

<bean id="authenticationEntryPoint"
class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
<property name="realmName" value="Protected atlight"/>
</bean>

<bean id="authenticationManager"
class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
</list>
</property>
</bean>

<bean id="daoAuthenticationProvider"
class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="simpleUserDetailsService"/>
</bean>

<!-- a simple simple UserDetailsService -->
<bean id="simpleUserDetailsService"
class="com.blogspot.ancientprogramming.security.SimpleUserDetailsService" />

<bean id="httpRequestAccessDecisionManager"
class="org.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<ref local="roleVoter"/>
</list>
</property>
</bean>

<bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter">
<property name="rolePrefix" value=""/>
</bean>
</beans>


web.xml
Together with this spring, acegi configuration in your web.xml you are up and running.
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<display-name>Archetype Created Web Application</display-name>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/securityContext.xml</param-value>
</context-param>

<filter>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

Sample (download)
I also provided a simple webapp demonstrating the implementation, just:
  1. download
  2. unzip
  3. type $mvn jetty:run
  4. go to: http://localhost:8080/basicAcegiExample
  5. type user, password as credentials

A badly packaged project will break builds!

I have stumpled across many comments on different blogs bashing maven for being a bad build tool. To me it seems that an era of "hate maven" is rising and many people seems to just blindfolded follow the horde of maven bashers.

It seems to me that people tend to forget what maven brings to a project.

  • Convention above configuration.
  • Dependency management.
  • A bunch of default plugins ready to be used. (You can argue the quality of all opensource plugins, but I really think it is getting better)
A thing like dependency management is one of the greatest benefits. Luckily I have forgot the old days where precious time was spend looking for dependencies need by other dependencies.

Although maven provides many benefits I ran into one of the things that one could call a bad side effect of using maven and its transitive dependency management.

The springframework is distributed in two different ways.
As a single artifact containing the complete spring distribution and as a much more fine grained distribution where each artifact contains a logical spring module.
As it all seems fine and interface21 probably think they are pleasing the broader audience by providing the different distributions, it brings a bigger problem to the surface.

By providing the same code in different artifacts you introduces the risk of a project to unintentionally depend on the same software in different versions.

In my case just adding the acegi 1.0.4 to my maven pom.xml broke our build - and I did not even configure or use any of the acegi code!

Ofcourse I wasn't late to blame maven. As the problem showed up by just modifying my pom.xml the problem couldn't be blamed on anybody else but maven.

Some exercises with the -X option shed some light on my problem:
Acegi 1.0.4 depend on the fine grained distributions of spring 2.0.4 modules, but as it happens I already had a dependency to the full spring 2.0.5 artifact. Dependency resolution interprets the to versions of the same software as different artifacts - and if you stick strictly to the maven dependency resolution rules they sure are different!

A dependency is defined uniquely as follows:
<groupid><artifactId><version><package>

As the version changes, maven takes care of using the latest version. But with different artifactnames containing the same code, you are most likely leaving your users of your library with a classloading issue just around the corner.

Hence the cause of the problem was lying outside maven.

Now you would probably tell me that I should only use the fine grained spring dependencies - but I was probably lazy and sure others out there are lazy too.

My experience sums up to the following rules of thumb:
  1. Apply DRY to your artifacts distribution.
    If you repeat yourself in your artifacts you introduce risks (not the same type of risk though) as if you repeat your code.
  2. Choose your groupId wisely and do not change it again - ever.
After blaming Spring I can tell that Spring isn't the only one to break dependency rules of thumb.
Ehcache has changed its groupId between version 1.2.3 to 1.2.4 and bingo! You have to different artifacts from a dependency resolution point of view.

Conclusion
Even with the quirks I just described I still think maven dependency management it is fare better than the good old plain Ant days!

Hints
If you suspect that you have run the same problem as I did, I suggest you run maven with the -X option as it prints the complete dependency resolution tree. From there you can find what transitive dependencies to exclude.
If you prefer Ant you should take look at the dependency management tool Ivy, but that subject is worth its own blogpost...

Thursday, 9 August 2007

What web 2.0 really is

A couple of days ago a colleague and I talked about what services we use on the internet. As our conversation evolved I once again remembered how I first looked at what we today denote Web 2.0.

As a system developer I tend to see everything from a technical point of view and of course I used the same perspective as the Web 2.0 accelerated a couple of years ago.

I remember asking myself the question:

How can a "simple" asynchronous call be hyped that much?

The fact that data could be fetched asynchronously was already easy to implement using iframes.
I had already done that on a project where we implemented a browser based settop-box client, so how could a simple XMLHttpRequest object start such a revolution?
(In fact the JSF component library ADF Faces still uses frames instead of the XHR object).

As time went by I found out that web 2.0 wasn't a technology, but much more a social thing, that to some extend benefits from the fact that the asynchronous technology got the well known AJAX name and a standard XHR object was implemented in the mainstream browsers.

Linked in, Facebook, Jaiku, Flickr etc. is the kind of services that really draws the web 2.0 picture and not some low level implementation as I once was nearly fooled to believe.

Now we - as end-users - only have to select what services we like to use as they seems to pop-up faster than we can fill in the registration forms.