Acegi security implementation by flurdy
Spring Framweork Acegi Security

A quick description on how to implement the Acegi authentication and authorization into your spring based web app.

Insert the following into you web.xml
<filter> <filter-name>Acegi Processing Filter</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 Processing Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class> </listener>
Then either add the following to your spring applicationContext.xml file, or import it into it as a seperate security.xml file.
<bean id="jdbcAuthenticationDao" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl"> <property name="dataSource"><ref bean="datasourceAuthentication"/></property> <property name="usersByUsernameQuery"> <value>SELECT username,password,'true' as enabled FROM users WHERE username = ? and enabled = 1</value> </property> </bean> <!-- <bean id="memoryAuthenticationDao" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl"> <property name="userMap"> <value> johnsmith=longshaedpassword,ROLE_SUPER,ROLE_ADMIN,ROLE_USER </value> </property> </bean> --> <bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.ShaPasswordEncoder"/> <bean id="saltSource" class="org.acegisecurity.providers.dao.salt.SystemWideSaltSource"> <property name="systemWideSalt" value="springRocks"/> </bean> <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"> <property name="userDetailsService"> <ref local="jdbcAuthenticationDao"/> </property> <property name="passwordEncoder" ref="passwordEncoder"/> <property name="saltSource" ref="saltSource"/> </bean> <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"> <property name="providers"> <list> <ref bean="rememberMeAuthenticationProvider"/> <ref bean="daoAuthenticationProvider"/> </list> </property> <!-- <property name="sessionController"><ref bean="concurrentSessionController"/></property> --> </bean> <!-- <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"> <property name="authenticationManager"> <ref bean="authenticationManager"/> </property> <property name="rememberMeServices"> <ref bean="rememberMeServices"/> </property> <property name="authenticationFailureUrl"> <value>/login.html?error=1</value> </property> <property name="defaultTargetUrl"> <value>/</value> </property> <property name="filterProcessesUrl"> <value>/loginform.do</value> </property> </bean> <bean id="authenticationEntryPoint" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"> <property name="loginFormUrl"> <value>/login.html</value> </property> </bean> <bean id="digestProcessingFilter" class="org.acegisecurity.ui.digestauth.DigestProcessingFilter"> <property name="userDetailsService"><ref bean="authenticationManager"/></property> <property name="authenticationEntryPoint"><ref local="digestProcessingFilterEntryPoint"/></property> <property name="userCache"><ref local="userCache"/></property> </bean> <bean id="digestProcessingFilterEntryPoint" class="org.acegisecurity.ui.digestauth.DigestProcessingFilterEntryPoint"> <property name="realmName"><value>Contacts Realm via Digest Authentication</value></property> <property name="key"><value>acegi</value></property> <property name="nonceValiditySeconds"><value>10</value></property> </bean> --> <bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter"> <property name="authenticationManager"><ref bean="authenticationManager"/></property> <property name="authenticationEntryPoint"><ref bean="authenticationEntryPoint"/></property> <!-- <property name="rememberMeServices"> <ref bean="rememberMeServices"/> </property> --> </bean> <bean id="authenticationEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint"> <property name="realmName"><value>Mail admin secure area</value></property> </bean> <bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter"/> <bean id="accessDecisionManager" class="org.acegisecurity.vote.UnanimousBased"> <property name="allowIfAllAbstainDecisions"> <value>false</value> </property> <property name="decisionVoters"> <list> <ref local="roleVoter"/> </list> </property> </bean> <!-- <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"> <property name="authenticationEntryPoint"> <ref bean="authenticationProcessingEntryPoint"/> </property> </bean> --> <bean id="securityEnforcementFilter" class="org.acegisecurity.intercept.web.SecurityEnforcementFilter"> <property name="filterSecurityInterceptor"> <ref bean="filterInvocationInterceptor"/> </property> <property name="authenticationEntryPoint"> <ref bean="authenticationEntryPoint"/> </property> </bean> <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"> <property name="authenticationManager"> <ref bean="authenticationManager"/> </property> <property name="accessDecisionManager"> <ref bean="accessDecisionManager"/> </property> <property name="objectDefinitionSource"> <value> CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT /super/**=ROLE_SUPER /**=ROLE_ADMIN </value> </property> </bean> <bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter"> <property name="rememberMeServices"><ref local="rememberMeServices"/></property> </bean> <bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices"> <property name="userDetailsService"><ref local="jdbcAuthenticationDao"/></property> <property name="key" value="springRocks" /> <property name="tokenValiditySeconds"><value>14400</value></property> </bean> <bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider"> <property name="key" value="springRocks" /> </bean> <bean id="concurrentSessionFilter" class="org.acegisecurity.concurrent.ConcurrentSessionFilter"> <property name="sessionRegistry"> <ref local="sessionRegistry" /> </property> <property name="expiredUrl"> <value>/</value> </property> </bean> <bean id="concurrentSessionController" class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl"> <property name="maximumSessions"><value>1</value></property> <property name="exceptionIfMaximumExceeded" value="true"/> <property name="sessionRegistry"> <ref bean="sessionRegistry"/> </property> </bean> <bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl"/> <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"> <property name="context"> <value> org.acegisecurity.context.SecurityContextImpl </value> </property> </bean> <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"> <property name="filterInvocationDefinitionSource"> <value> CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT /**=concurrentSessionFilter,httpSessionContextIntegrationFilter,basicProcessingFilter,rememberMeProcessingFilter,securityEnforcementFilter </value> </property> </bean> <!-- authenticationProcessingFilter rememberMeProcessingFilter, digestProcessingFilter basicProcessingFilter -->
This setup uses basic authentication and Sha encoded database passwords. And it also remembers users between sessions.

To switch to storing plain text passwords, comment out the passwordEncoder and saltSource in the daoAuthenticationProvider.

If you do not need database stored passwords, comment out jdbcAuthenticationDao, uncomment memoryAuthenticationDao, In daoAuthenticationProvider, swap the userDetailsService from jdbcAuthenticationDao to memoryAuthenticationDao.

To switch to form based authentication, uncomment authenticationProcessingFilter and the first authenticationEntryPoint. Comment out basicProcessingFilter and the second authenticationEntryPoint. Then replace the basicProcessingFilter in the filterChainProxy with authenticationProcessingFilter.

To switch to digest based authentication, you can not use encoded passwords in you dao. Then also uncomment digestProcessingFilter and digestProcessingFilterEntryPoint. Comment out basicProcessingFilter and the second authenticationEntryPoint. Then replace the basicProcessingFilter in the filterChainProxy with digestProcessingFilter.

To turn off remember me, comment out rememberMeAuthenticationProvider in the provider list of authenticationManager, comment out rememberMeServices" property in authenticationProcessingFilter, comment out the rememberMeProcessingFilter, rememberMeServices and rememberMeAuthenticationProvider beans, and remove it from the filteChainProxy
Here are a simple login view if using form based authentication.
#if( $params.error ) <h5 class="error">Uhuh! Didnt like that</h5> #end <table border="0"> <form action="$request.contextPath/loginform.do" method="get"> <tr> <td>Username:</td> <td><input type="text" name="j_username" /></td> </tr> <tr> <td>Password:</td> <td><input type="password" name="j_password" /></td> </tr> <tr> <td>Remember login?</td> <td> <input type="checkbox" name="_acegi_security_remember_me" /> </td> <tr> <td colspan="2"><input type="submit" value="login" /></td> </tr> </form> </table>
This set up is based on Acegi version 1.0.rc2.

The final version of release 1.0 has some minor tweaks. All of which are detailed on the Acegi website.
Any comments, contact me. Be aware I am rubbish in replying.. sorry.