Sunday, April 19, 2009

Posting Source Code in Blogger

This should be so easy - BBEdit code tags anyone? Here's a nice and easy solution for posting cleanly formatted code samples in blogger: FormatMySourceCode

Saturday, April 18, 2009

Spring Security, HTTP Basic plus Form Authentication

This is probably pretty common - we have a restful API that can be used for third-party systems integration but which is also used to support our AJAX user interface.

To support both cases, I want HTTP-Basic and Form authentication to protect the service URLs - ideally spring security would be configured to transparently support either one.

I finally got this working but not as cleanly as I might have hoped for - if anyone out there has an improved solution I would love to hear it!

1. expose the API on two URLs, I created one service mapping for /api and one for /services both mapped to the same servlet, one will be http-basic and one will use form-login

2. Change the default filter-name that Spring uses:
<filter-mapping>
<filter-name>customSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>



3. Configure spring security using the custom filter chain. Use a new instance of HttpSessionContextIntegrationFilter with allow session creation set to false to prevent the wasted overhead of session creation for http basic clients, who will likely not present JSESSIONID cookies. (thanks to magomarcelo here http://raibledesigns.com/rd/entry/upgrading_to_spring_security_2 for that one)


    <http auto-config="false">

<intercept-url pattern="/api/**" access="ROLE_USER,ROLE_GROUPADMIN,ROLE_SYSADMIN" />

<http-basic/>
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?msg=fail" default-target-url="/" always-use-default-target="true" />
<logout logout-url="/logout" logout-success-url="/login.jsp" />

</http>


<beans:bean id="basicExceptionTranslationFilter"
class="org.springframework.security.ui.ExceptionTranslationFilter">
<beans:property name="authenticationEntryPoint" ref="_basicAuthenticationEntryPoint"/>
<beans:property name="accessDeniedHandler">
<beans:bean class="org.springframework.security.ui.AccessDeniedHandlerImpl"/>
</beans:property>
</beans:bean>


<beans:bean id="httpSessionContextIntegrationFilterWithASCFalse"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter">
<beans:property name="allowSessionCreation" value="true"/>
</beans:bean>



<beans:bean id="customSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
<filter-chain-map path-type="ant">
<filter-chain pattern="/api/**"
filters="httpSessionContextIntegrationFilterWithASCFalse,_basicAuthenticationFilter,
basicExceptionTranslationFilter,
_filterSecurityInterceptor"/>
<filter-chain pattern="/**"
filters="_httpSessionContextIntegrationFilter,_logoutFilter,_formLoginFilter,
_securityContextHolderAwareRequestFilter,
_exceptionTranslationFilter,
_filterSecurityInterceptor"/>

</filter-chain-map>
</beans:bean>